El otro día estaba leyendo un poco sobre Unit Testing y vi algunos ejemplos en los que las personas crean una interfaz de repositorio (es decir IExampleRepository
) y luego crean el repositorio real ( public class ExampleRepository : IExampleRepository
) y un repositorio que se utilizará para las pruebas unitarias ( FakeExampleRepository : IExampleRepository
).
En el IExampleRepository
estaban implementando los mismos métodos que en el ExampleRepository
, sin embargo, con diferentes consultas Linq.
¿Cuál es exactamente el objetivo aquí? ¿Pensé que una parte de la unidad que prueba su código es asegurarse de que un método funcione correctamente? Pero cuando uso dos consultas totalmente diferentes, una para 'real' y otra en la prueba, ¿qué sentido tiene la prueba?
ExampleRepository
, entonces es mejor usar un simulacro. La justificación es que no está haciendo pruebas unitarias del repositorio sino algo más.ExampleRepository
, use la cosa real. Si está realizando pruebas unitariasRepositoryController
, solo debe usar unaFakeExampleRepository
que devuelva valores especificados previamente. De esta manera, si un error apareceExampleRepository
, solo la prueba de la unidad fallará;RepositoryController
las pruebas continuarán teniendo éxito, por lo que sabe que no hay un error allí. Si el controlador usara el repositorio real, ambos estarían fallando y no sabría si tuvo 1 error o 2.Estoy de acuerdo con las dos respuestas de jk. y Jan Hudec, dan muy buena información. Pero pensé que agregaría un poco.
Su primera pregunta ("¿Cuál es exactamente el objetivo aquí?") Es importante. En el caso que está describiendo, el objetivo real es probar las clases que están utilizando la
IExampleRepository
interfaz, no probar las implementaciones del repositorio. La creación de leFakeExampleRepository
permite probar esas clases de clientes sin preocuparse por los detalles de la clase de repositorio real.Esto es especialmente cierto si el objeto que está intentando configurar dificulta las pruebas (por ejemplo, accede al sistema de archivos, llama a un servicio web o habla con una base de datos). Mediante el uso de interfaces (y otras técnicas similares), mantiene el acoplamiento bajo. Por lo tanto, la clase
X
solo necesita saber acerca de la interfaz y no necesita conocer los detalles de implementación. El objetivo es asegurarse de que la claseX
esté haciendo lo correcto.Burlarse (o tropezar, fingir ... hay diferencias matizadas) es una herramienta poderosa para pruebas unitarias y TDD. Pero puede ser complicado crear y mantener manualmente estas implementaciones. Por lo tanto, la mayoría de los idiomas ahora tienen bibliotecas falsas para ayudar. Como estás usando C #, recomendaría Moq porque es simple y muy poderoso. Luego puede probar con la interfaz sin acumular código adicional para las implementaciones simuladas.
fuente
the real objective is to test the classes that are utilizing the IExampleRepository interface
Eso no es estrictamente cierto. El objetivo es probarlo independientemente del IExampleRepository. +1 por recomendar un buen marco de aislamiento sin embargo.IExampleRepository
porque la clase bajo prueba está acoplada a esa interfaz. Pero es independiente de cualquier implementación de la interfaz. Sin embargo, admito que mi explicación probablemente podría usar un poco más de delicadeza. :)Aislamiento.
La idea de una unidad lo prueba para probar la unidad de código más pequeña posible . Para ello, aislarlo de todos los demás códigos de producción en la prueba.
Al crear clases falsas, el único código de producción es la clase bajo prueba.
Si crea un repositorio falso correctamente y la prueba falla, sabe que el problema está en el código bajo prueba. Esto le brinda el beneficio del diagnóstico de forma gratuita.
Eche un vistazo a los marcos de aislamiento (como Moq según lo sugerido por @Allan) para poder generar estas falsificaciones rápidamente para configurar las condiciones de prueba y utilizarlas para hacer valer.
fuente
Hay tres razones por las que es posible que desee proporcionar una instancia simulada para la prueba unitaria:
fuente