¿Cómo evito que mis pruebas de unidad que requiere de conocimiento sobre partes internas de ejecución al utilizar los objetos de imitación?

StackOverflow https://stackoverflow.com/questions/3448121

Pregunta

Todavía estoy en las etapas de aprendizaje en relación con la unidad de pruebas y en particular con respecto a burlarse (estoy usando el PascalMock y DUnit marcos). Una cosa que ahora tropecé fue que no pude encontrar un camino alrededor de la codificación dura detalles de implementación de la clase / interfaz probado en mi prueba de la unidad y que sólo se siente mal ...

Por ejemplo: Quiero probar una clase que implementa una interfaz muy sencilla para la lectura y escritura de configuración de la aplicación (básicamente nombrar pares / valor). La interfaz que se presenta al consumidor es completamente agnóstico a dónde y cómo los valores se almacenan en realidad (por ejemplo, registro, INI-archivo, XML, bases de datos, etc.). Naturalmente, la capa de acceso se implementa aún una clase diferente que consigue inyecta en la clase probado en la construcción. He creado un objeto de burla para esta capa de acceso y ahora soy capaz de probar completamente la clase de interfaz de la aplicación sin tener que leer o escribir cualquier cosa a cualquier / INI-archivo de registro / lo que sea.

Sin embargo, con el fin de garantizar los comporta simuladas exactamente como la cosa real cuando se accede por la clase pedida, mis pruebas unitarias tienen que establecer el objeto de burla por definir de manera muy explícita llamadas a métodos esperados y los valores de retorno esperados por la clase pedida . Esto significa que si alguna vez tiene que realizar cambios en la interfaz de la capa de acceso o en la forma en que los usos de la clase probados que la capa I también tendrán que cambiar las pruebas de la unidad de la clase que utiliza internamente esa interfaz aunque el < strong> interfaz de la clase que en realidad estoy probando no ha cambiado en absoluto. Es esto algo sólo voy a tener que vivir con burla cuando se utiliza o hay una mejor manera de diseñar las clases dependencias que evitaría esto?

¿Fue útil?

Solución

  

Es esto algo sólo voy a tener que   vivir con burla cuando se utiliza o hay   una mejor manera de diseñar el   clase dependencias que evitarían   esto?

Muchas veces se burla (en particular los marcos sensibles como JMock) que obligan a la cuenta de detalles que no se relacionan directamente con el comportamiento que está tratando de prueba, y en ocasiones esto puede incluso ser útil mediante la exposición de código sospechoso que es hacer demasiado y tiene demasiadas llamadas / dependencias.

Sin embargo, en su caso, si leo su descripción derecha, parece que usted realmente no tiene un problema. Si el diseño de la capa de lectura / escritura correcta y con un nivel adecuado de abstracción, que no debería tener que cambiarlo.

  

Esto significa que si alguna vez tiene   para realizar cambios en la interfaz de   la capa de acceso o de la forma en que   la clase probado utiliza esa capa I   También tendrá que cambiar la unidad   Las pruebas para la clase que internamente   usos que se interconectan a pesar de que la   interfaz de la clase realidad soy   la prueba no ha cambiado en absoluto.

No es el punto de escribir la capa de acceso abstraída para evitar esto? En general, después de la abierto / cerrado principio , una interfaz de este tipo no debe el cambio y no debe romper el contrato con la clase que lo consume, y por extensión no va a romper las pruebas unitarias tampoco. Ahora bien, si cambiar el orden de las llamadas a métodos, o tienen que realizar nuevas llamadas a la capa abstracta, entonces, sí, sobre todo con algunos marcos, sus expectativas simulacros se romperán. Esto es sólo una parte del costo de la utilización de burla, y es perfectamente aceptable. Pero la propia interfaz debe, en general, se mantienen estables.

Otros consejos

  

para garantizar los simulacros se comporta exactamente como la cosa real cuando se accede por la clase pedida, mis pruebas unitarias tienen que establecer el objeto de burla definiendo explícitamente las llamadas a métodos muy esperados y los valores de retorno esperados por la clase pedida.

correcta.

  

cambios en la interfaz de la capa de acceso o a la forma en que los usos de clase probados que la capa I serán también tener que cambiar las pruebas de unidad

correcta.

  

a pesar de que la interfaz de la clase que en realidad estoy probando no ha cambiado en absoluto.

"En realidad la prueba"? ¿Quieres decir que la clase interfaz expuesta? Esta bien.

La forma en la clase (interfaz) "probado" utiliza los medios de capa de acceso que ha cambiado la interfaz interna de la capa de acceso. cambios en la interfaz (incluso los internos) requieren cambios de prueba y pueden conducir a la rotura si ha hecho algo mal.

No hay nada malo con esto. De hecho, el objetivo es que cualquier cambio en la capa de acceso debe requieren cambios en los simulacros para asegurar que las "obras" de cambio.

No se supone

Pruebas de ser "robusto". Se supone que debe ser frágiles. Si realiza un cambio que altera el comportamiento interno, entonces las cosas puede descanso. Si las pruebas eran demasiado robusta que no lo harían prueba de cualquier cosa - que trabajaría solo. Y eso está mal.

Las pruebas sólo deben trabajar por la razón exacta por la derecha.

Sólo para poner algunos nombres a su ejemplo,

  • implementos RegistryBasedDictionary el Papel (interfaz) Dictionary.
  • RegistryBasedDictionary tiene una dependencia en el RegistryAccessor papel, implementado por RegistryWinAPIWrapper.

Usted está interesado actualmente en pruebas RegistryBasedDictionary. Las pruebas unitarias serían inyectar una dependencia mock para el Papel RegistryAccessor y pondrían a prueba la interacción de esperar con las dependencias.

  • El truco para evitar la prueba de mantenimiento innecesario es " especificar con precisión lo que debe suceder .. y no más ." (De el libro GOOS (lectura obligada para maqueta con sabor TDD), por lo que si el orden de las llamadas a métodos de dependencia no importa, no especifican en la prueba. que te deja libre para cambiar el orden de las llamadas en la aplicación.)
  • Diseño las funciones de tal manera que el que no contienen cualquier fuga procedente de las implementaciones reales - mantener las funciones de ejecución agnóstica .

La única razón para cambiar las pruebas RegistryBasedDictionary, sería un cambio en el comportamiento de RegistryBasedDictionary y no en cualquiera de sus dependencias. Así que si su interacción con sus dependencias o el cambio de roles / contratos, las pruebas tendría que ser actualizado . Ese es el precio de las pruebas basadas en la interacción que necesita para pagar, por la flexibilidad de la prueba de forma aislada. Sin embargo, en la práctica, no se que sucede a menudo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top