5

Digamos que está escribiendo una función para verificar si una página fue alcanzada por la URL apropiada. La página tiene un código "canónico"; por ejemplo, mientras se puede acceder a una página en stackoverflow.com/questions/123, preferiríamos (por motivos de SEO) redirigirla a stackoverflow.com/questions/123/how-do -i-move-the-turtle-in-logo - y la redirección real está contenida de forma segura en su propio método (por ejemplo, redirectPage ($ url)), pero ¿cómo se prueba adecuadamente la función que lo llama?Funciones de pruebas unitarias con efectos secundarios?

Por ejemplo, tomemos la siguiente función:

function checkStub($questionId, $baseUrl, $stub) { 
    canonicalStub = model->getStub($questionId); 
    if ($stub != $canonicalStub) { 
    redirectPage($baseUrl . $canonicalStub); 
    } 
} 

Si se va a prueba unidad de la función checkStub(), ¿no la redirección en el camino?

Esto es parte de un problema mayor en el que ciertas funciones parecen ser demasiado grandes y dejan el reino de las pruebas unitarias y en el mundo de las pruebas de integración. Inmediatamente, mi mente piensa que los enrutadores y controladores tienen este tipo de problemas, ya que probarlos necesariamente conduce a la generación de páginas en lugar de limitarse a su propia función.

¿Fallo en las pruebas unitarias?

+0

más despacio ... y volver a pensar en qué es lo que realmente tratando de probar aquí ... Si se quita la redirección, la checkStub método no hace mucho, así que no estoy seguro de la verdadera prueba aquí. Por lo general, prueba los efectos secundarios que causa dicha función. – Gishu

+0

@gishu: sí, es un ejemplo increíblemente defectuoso generado a partir de un problema anterior que resolví desde entonces ... el problema fue solucionado, pero el ejemplo (redirigir) quedó atorado en mi cabeza.Enfóquese en el final de la pregunta: enrutadores, controladores, como la verdadera cuestión. ¿Cómo pruebo las funciones cuyo enfoque es en gran medida "crear cosas", pero que aún deben ser probados debido a su propio orden interno y la lógica. Voy a desmayarme ahora y probablemente edite el infierno de esta pregunta por la mañana. Espero que puedas ver mi intención ahora (podría ser útil saber que soy nuevo para las pruebas unitarias). – AgentConundrum

+0

Acaba de decir que está mezclando la lógica con la creación de objetos, lo que dificulta las pruebas unitarias. ¿Puedes dividir estas dos preocupaciones? Si es así, escribir las pruebas de su unidad será bastante trivial. – strager

Respuesta

0

Parece que tiene otro caso de prueba. Debe verificar que el talón se identifica correctamente como un talón con pruebas positivas y negativas, y debe comprobar que la página a la que se le redirige es correcta.

¿O entiendo totalmente la pregunta?

+2

¿Puede usted editar su pregunta y arreglar su typos kthx? – strager

1

Usted dice ...

Esto es parte de un problema mayor en ciertas funciones parecen ser demasiado grande y dejar el reino de las pruebas unitarias y en el mundo de las pruebas de integración

Creo que esta es la razón por la cual las pruebas unitarias son (1) duras y (2) conducen a un código que no se desmorona por su propio peso. Tienes que ser meticuloso para romper todas tus dependencias o terminas con pruebas de unidad == pruebas de integración.

En su ejemplo, se inyectaría un redirector como dependencia. Utiliza un simulacro, doble o espía. Luego haces las pruebas cuando @atk establece. A veces no vale la pena. Más a menudo te obliga a escribir un mejor código. Y es difícil hacerlo sin un contenedor de IOC.

1

Esta es una vieja pregunta, pero creo que esta respuesta es relevante. @Rob indica que se inyectaría un redirector como dependencia y, por supuesto, esto funciona. Sin embargo, su problema es que no tiene una buena separación de preocupaciones.

Necesita hacer que sus funciones sean lo más atómicas posible, y luego componer una funcionalidad más grande usando las funciones granulares que ha creado. Usted escribió esto:

function checkStub($questionId, $baseUrl, $stub) { 
    canonicalStub = model->getStub($questionId); 
    if ($stub != $canonicalStub) { 
    redirectPage($baseUrl . $canonicalStub); 
    } 
} 

me gustaría escribir esto:

function checkStubEquality($stub1, $stub2) { 
    return $stub1 == $stub2; 
    } 

    canonicalStub = model->getStub($questionId); 
    if (!checkStubEquality(canonicalStub, $stub)) redirectPage($baseUrl . $canonicalStub);