Soy un principiante en las pruebas de código, y fui una assert
prostituta antes. Una cosa que me preocupa en las pruebas unitarias es que a menudo requiere que usted haga public
(o al menos internal
) campos que de private
otro modo habrían sido , para eliminarlos readonly
, crear private
métodos protected virtual
, etc.
Recientemente descubrí que puedes evitar esto usando cosas como la clase PrivateObject para acceder a cualquier cosa en un objeto a través de la reflexión. Pero esto hace que sus pruebas sean menos mantenibles (las cosas fallarán en la ejecución en lugar del tiempo de compilación, se romperá con un simple cambio de nombre, es más difícil de depurar ...). Qué opinas de esto ? ¿Cuáles son las mejores prácticas en pruebas unitarias con respecto a la restricción de acceso?
editar: considere, por ejemplo, que tiene una clase con un caché en un archivo en el disco, y en sus pruebas desea escribir en la memoria.
fuente
Respuestas:
Nunca deberías tener que
Especialmente la no lectura de un campo puede hacer que un objeto inmutable sea mutable, y eso sería un desastre.
Sus pruebas deben considerar sus objetos como cajas negras ( Wikipedia ), lo que significa que solo deben preocuparse por la interfaz pública de los objetos, no con los detalles de su implementación.
Si un objeto no puede probarse suficientemente usando su interfaz pública, entonces necesita encontrar formas de proporcionar extensiones formales y útiles a su interfaz que faciliten la prueba. Por ejemplo, un sistema de registro con solo un par de métodos de Registro / Desregistro quizás se beneficiaría de un método IsRegistered incluso si no es necesario para la aplicación en cuestión; aun así, es una extensión formal y útil de la interfaz, y, por cierto, acomodará las pruebas.
Lo importante es que cambiar la implementación del objeto no debería requerir que cambie la prueba de la unidad. En teoría, debería poder escribir la prueba unitaria una vez, y luego pedirle a múltiples programadores que codifiquen múltiples implementaciones completamente diferentes del objeto a probar para trabajar con la prueba unitaria.
fuente
private
métodosprotected virtual
para ayudar con la burla en las pruebas se considera una mala práctica?En C # puede usar
InternalsVisibleToAttribute
para permitir que su ensamblaje de prueba vea lasinternal
clases en el ensamblaje que está probando. Parece que ya lo sabes.En la mayoría de los casos, solo estoy interesado en probar la API pública de mi ensamblado. En un caso en el que quiero hacer una prueba de caja blanca de alguna unidad, muevo el código a una
internal
clase y lo convierto en unpublic
método de esa clase. Entonces puedo codificar una prueba unitaria para esa clase.Esto se presta bien a la inyección de dependencia y al patrón de estrategia. Puede abstraer el método en una interfaz, inyectar la interfaz en el constructor de su objeto padre y simplemente probar que el padre delegue adecuadamente. Luego puede probar que el objeto secundario se comporta adecuadamente. Esto hace que todo sea más modular.
fuente
En mi experiencia, es mejor no exponer las partes internas de su clase especialmente para el examen. Aunque parezca que esto hace que la prueba sea más fácil de escribir. La prueba es el primer cliente de su clase, por lo que si es difícil probar su clase a través de su interfaz pública, probablemente será difícil usar su clase en otros lugares también.
Lo fácil que es probar la clase a través de su API pública son comentarios sobre lo fácil que será usar la clase. Piense en las pruebas parcialmente como una forma de crear un prototipo del uso de su clase.
Intente considerar por qué su prueba necesita detectar algo sobre la clase que no está disponible a través de la API pública. ¿Quizás su clase está haciendo demasiado y necesita descomponerse en un grupo de clases cooperativas? Luego puede burlarse de algunas de las clases colaboradoras para sentir lo que está haciendo la clase bajo prueba.
Intente aplicar el principio de inversión de dependencia e introduzca interfaces entre sus clases que pueda burlarse en sus pruebas. Puede proporcionar a los colaboradores a su prueba utilizando la inversión de control .
También considere aplicar el principal "tell don't ask" para ayudar a estructurar la interfaz de su clase de una manera robusta y poco acoplada, donde se exponga la información correcta y se oculte el resto.
fuente
Personalmente, prefiero dejar el código que estoy probando lo más puro posible y si el código de prueba necesita hacks (y en punteros desagradables en C ++, etc.), estoy feliz de hacerlo.
fuente
¡La visibilidad de su código no tiene nada que ver con las pruebas de su unidad!
Usted hace que sus métodos sean privados, no con el propósito de ocultarlos de las pruebas y no los hace públicos para exponerlos a las pruebas, ¿verdad? Esta es su implementación que es esencial aquí, no las pruebas, esos servidores como prueba de su código, pero no son su código .
Hay muchas maneras de habilitar el acceso a métodos y propiedades ocultos (privados o internos). Muchos marcos de prueba e IDEs (por ejemplo, Visual Studio) lo apoyan aquí al generar todo lo necesario para el acceso, solo tiene que crear sus casos de prueba. Entonces, ¿por qué preocuparse? Mejor mantenga su código limpio y ordenado.
fuente