Estamos utilizando StructureMap en un nuevo proyecto de desarrollo de software. Uno de los miembros del equipo ha implementado una prueba de unidad que básicamente prueba la configuración del contenedor de StructureMap . Hace esto haciendo lo siguiente;
- Cuenta el número de instancias de ensamblajes configurados para clases en el espacio de nombres de nuestra aplicación.
- Define instancias esperadas a nivel de clase
- Afirma que las instancias esperadas coinciden con el total de instancias encontradas.
- Afirma que las instancias esperadas coinciden con las definidas en la prueba
Un ejemplo de esto es;
var repositories = container.GetAllInstances<IEnvironmentRepository>();
Assert.AreEqual(1, repositories .Count());
foundInstances = foundInstances + repositories .Count();
También tenemos 'pruebas unitarias' para la siguiente clase;
public MyClass(IEnvironmentRepository environmentRepository)
{
}
En estas pruebas, nos burlamos de IEnvironmentRepository, por lo que no lo inyectaríamos desde el contenedor como sucedería en el sistema en vivo.
Un colega ignoró la prueba de la unidad en la configuración del mapa de estructura con un comentario en la línea de "La prueba de la unidad solo prueba su propia configuración". Obviamente, este era el propósito de la prueba y, en mi opinión, es perfectamente válido. Le pedí al tipo que ignoró la prueba que eliminara la configuración del mapa de estructura para IEnvironmentRepository
(con la prueba aún ignorada) y ejecutara el conjunto de pruebas de la unidad completa, todos pasaron. Luego ejecutamos la aplicación y se cayó porque la configuración del contenedor ahora no era válida. En mi opinión, esto demostró el valor de la prueba, mi colega aún no estaba de acuerdo. Simplemente declaró que no deberíamos probar la configuración, pero considero que esto está dentro del alcance de una prueba unitaria.
Entonces una serie de preguntas;
- ¿Es una prueba de unidad válida? Estamos probando la configuración de nuestro contenedor, no que el mapa de estructura funcione (pero puedo ver la superposición)
- Si no, ¿cómo puede validar la configuración sin probarla? ¿Cómo puede evitar que alguien elimine accidentalmente una línea de código requerida y la registre?
- ¿Debería la
MyClass
prueba unitaria resolver la instancia delIEnvironmentRepository
contenedor y pasar esto?
fuente
Respuestas:
Esta es una prueba automatizada perfectamente válida para tener. Los llamo "pruebas de arquitectura", ya que verifican la solidez de los componentes esqueléticos de su base de código.
¿El contenedor IoC puede resolver y componer todos los árboles de objetos en la aplicación? ¿Puede el mapeador automático mapear entre todos sus objetos registrados sin fallar? ¿La capa central en una arquitectura de cebolla no hace referencia a nada externo?
Estas pruebas pueden ahorrarle mucho tiempo cuando un error de configuración se cuela, señalando al culpable exacto. Los buenos marcos te darán mensajes de error muy precisos sobre lo que está mal y los recibirás tan pronto como ejecutes las pruebas (idealmente, continuamente) en lugar de enterrar en el fondo un seguimiento de la pila de tiempo de ejecución si tienes suerte.
Ya sean pruebas unitarias ... probablemente no, pero aún operan en la memoria en su mayor parte y funcionan bastante rápido. Por otra parte, no sé, no es como si hubiera una definición universalmente aceptada de prueba unitaria.
fuente
El problema con una prueba como esta que prueba las partes internas del programa, en lugar de un requisito del mismo. Es que la prueba puede fallar incluso si el programa funciona como se requiere.
En su caso, cada vez que cambia la configuración del contenedor, tal vez tenga una nueva dependencia que necesita inyectarse, interrumpe su prueba.
Además, si agrega el requisito de dependencia adicional, pero olvide agregarlo al contenedor y cambiar la prueba del contenedor. todo pasará, pero su programa se bloqueará.
Una mejor prueba automatizada sería iniciar el programa y ver si falla.
Debe detectar estos tipos de error en las pruebas de integración o UI, incluso si caen en las pruebas unitarias.
Dicho esto, la creciente complejidad de la configuración del contenedor es una molestia. Quizás algunas pruebas "malas" valen la pena.
fuente
Código de prueba de pruebas unitarias. Cualquier cosa fuera de esto son "otras" pruebas automatizadas: llámelo como quiera. Parece que estás probando la configuración aquí. Si la configuración puede cambiar según el entorno, no pertenece a una prueba unitaria. Considere agregar un atributo de prueba para indicar que la prueba es de un tipo diferente a las otras pruebas.
fuente
La responsabilidad del contenedor de inyección de dependencia es pegar diferentes módulos en una aplicación de trabajo .
Si escribe pruebas automatizadas para su aplicación, debe tener pocas pruebas de "integración (o aceptación) que ejecuten pruebas" de principio a fin ", que probarán toda la tubería de su aplicación, que todos los módulos involucrados en un caso de prueba en particular estén pegados correctamente .
Por lo tanto, esas pruebas de integración fallarán si el contenedor de inyección de dependencia no se configuró correctamente. Lo que hace que las pruebas unitarias para el contenedor en sí sean inútiles, porque la prueba de integración debe mostrar posibles errores en la configuración del contenedor.
No es necesario que cubra todos los casos de prueba posibles en las pruebas de integración, solo un caso de prueba por función que cubre el camino completo desde la interfaz de usuario a la base de datos.
Si los casos de prueba de integración no cubren la creación de instancias de alguna dependencia particular, simplemente agregue dicha.
Con las pruebas de integración, puede cambiar libremente los contenedores sin tener que volver a escribir pruebas unitarias para su configuración.
fuente
OMI, las respuestas son:
¿Es una prueba de unidad válida? Estamos probando la configuración de nuestro contenedor, no que el mapa de estructura funcione (pero puedo ver la superposición)
Si no, ¿cómo puede validar la configuración sin probarla? ¿Cómo puede evitar que alguien elimine accidentalmente una línea de código requerida y la registre?
¿Debería la prueba de unidad MyClass resolver la instancia de IEnvironmentRepository del contenedor y pasar esto?
fuente
UnitTest verifica el comportamiento deseado de una unidad en separación .
Esto significa que cualquier tipo de configuración no está dentro del alcance de UnitTests .
No obstante, debe tener pruebas automatizadas para sus configuraciones, pero estas no son UnitTests ...
fuente