Estoy leyendo El arte de las pruebas unitarias de Roy Osherove. Estoy en la sección 7.2 Escribiendo pruebas mantenibles donde el autor tiene esta nota sobre el olor del código:
NOTA: Cuando refactoriza el estado interno para que sea visible para una prueba externa, ¿podría considerarse un olor a código (una señal de que algo podría estar mal en el diseño o la lógica del código)? No es un olor a código cuando refactoriza para exponer a los colaboradores. Es un olor a código si está refactorizando y no hay colaboradores (por lo que no necesita tropezar ni burlarse de nada).
EDITAR : Lo que el autor quiere decir con "colaboradores" son dependencias. Algunos de sus ejemplos de dependencias son clases que acceden a una base de datos o que acceden al sistema de archivos del sistema operativo. Aquí es donde define el trozo y comienza a usar la palabra colaborador:
Un stub es un reemplazo controlable para una dependencia existente (o colaborador ) en el sistema.
El autor no tiene un ejemplo de este olor a código y estoy teniendo problemas para entender / imaginar cómo se vería. ¿Alguien puede explicar esto un poco más y tal vez proporcionar un ejemplo concreto?
fuente
Respuestas:
Creo que esto es a lo que se está refiriendo el autor.
En mi ejemplo de código, tengo una ventana de tiempo que toma una cantidad de salida más un tiempo de inicio y finalización. La intención es dibujar una ventana de salida en un intervalo de tiempo de 24 horas. Se agrega una arruga cuando la hora de inicio es mayor que la hora de finalización porque es una ventana de tiempo que abarca la medianoche.
Puede escribir pruebas unitarias que ejerciten completamente el objeto sin exponer las variables privadas. Esos bools privados y plazos son los colaboradores a los que se refiere cuando expone los elementos internos para las pruebas unitarias. Según el libro, exponer esas partes internas NO sería un olor a código ya que son colaboradores.
Exponer el doble
output
sería un olor a código, ya que no es un colaborador: es un elemento oculto explícitamente por la clase misma que tiene una lógica condicionalGetOutput
para determinar qué debe devolverse.Excavar en los límites de tiempo / bools haría que las pruebas unitarias sean más completas. Él dice que esto es bueno.
Excavar en el doble
output
requeriría una lógica adicional en la prueba de su unidad que reflejara lo queGetOutput
estaba haciendo. Este sería el código de olor al que se refiere.fuente
Digamos que tenemos una clase de dominio, y esta clase de dominio tiene conocimiento directo de la capa de persistencia utilizando un Repositorio, que utiliza para exponer un método "Guardar" a nivel de instancia que los objetos que trabajan en la clase de dominio pueden llamar para persistir cambios hecho sin necesidad de conocer el mecanismo (si este es un diseño "bueno" es una discusión para otro día). Refactorizar la clase para exponer este Repositorio como una propiedad y / o un argumento de constructor, permitiendo así que se pase un Repositorio simulado que pueda garantizar que se realice la llamada adecuada, generalmente es algo bueno no solo para las pruebas sino también para la mantenibilidad general.
Ahora, al ser una clase de dominio, tiene datos de estado. Supongamos por un momento que una de las propiedades con estado tiene un campo de respaldo, y los accesores de propiedades prueban que una nueva entrada es válida en función de la actual (tal vez el nuevo valor nunca puede ser menor que el anterior). Debe probar esta validación, pero considera que hacerlo requiere acceso al campo de respaldo para establecer un valor inicial que luego intentará sobrescribir. Esto debería ser una bandera roja; si la prueba necesita acceder al campo de respaldo (que es un detalle de implementación; ningún consumidor debe siempretiene que saber que está allí) para que el objeto tenga un estado consistente para una prueba, entonces, ¿cómo podría el código de producción obtener un objeto consistente? Si hay un método para que el código de producción haga lo mismo que hace su prueba, entonces la prueba probablemente debería imitar de esa manera. Si no hay una forma válida para que el código de producción lleve el objeto a este estado, ¿por qué está probando este escenario?
fuente