Pregunta

Después de varios años de seguir las malas prácticas transmitidas por los 'arquitectos' en mi lugar de trabajo y pensar que debe haber una manera mejor, recientemente he estado leyendo sobre TDD y DDD y creo que los principios y prácticas serían una encaja perfectamente con la complejidad del software que escribimos.

Sin embargo, muchas de las muestras de TDD que he visto llaman a un método en el objeto de dominio y luego prueban las propiedades del objeto para garantizar que el comportamiento se ejecute correctamente.

Por otro lado, varias personas respetadas en la industria (Greg Young más notablemente con sus charlas sobre CQRS) abogan por encapsular completamente cada objeto de dominio eliminando todos los 'captadores'.

Por tanto mi pregunta es:¿Cómo se prueba la funcionalidad de un objeto de dominio si está prohibido recuperar su estado?

Creo que me estoy perdiendo algo fundamental, así que no dudes en llamarme idiota e iluminarme; cualquier orientación sería muy apreciada.

¿Fue útil?

Solución

Lo que estás describiendo es verificación estatal en donde afirma sobre el estado del objeto de dominio. Hay una rama de TDD que se llama verificación de comportamiento que utiliza objetos simulados.

La verificación de comportamiento le permite especificar qué métodos deben llamarse y, si lo desea, qué métodos no se llaman.

Mire este artículo de Martin Fowler para obtener más detalles: Los simulacros no son trozos.

Otros consejos

Ok, esta respuesta es un año demasiado tarde ;-)

Pero cuando desea probar los modelos CQRS, puede hacer afirmaciones sobre los eventos de dominio disparados en lugar de afirmaciones sobre el estado de la entidad.

Por ejemplo, si desea probar si llama: Customer.Rename ("Foo") da como resultado el comportamiento correcto.

En lugar de probar si Customer.name es igual a "foo", prefiere probar si hay un evento pendiente de nombre de nombre con el valor "foo" en su tienda de eventos pendiente. (en su UOW o en su lista de eventos de entidad dependiendo de la implementación)

Si realmente va a ir tan lejos como para prohibir la recuperación del estado, entonces se limitará a las pruebas de comportamiento, probablemente a través de un marco burlón como Typemock, que tiene el poder de rastrear el comportamiento de su objeto. Si puede hacer BDD puro, en teoría puede afirmar la corrección de todo su sistema por la forma en que se comporta.

En la práctica, he descubierto que BDD es más frágil en muchos casos que solo pruebas con estado. Si bien algunas personas pueden pedir una determinada teoría, solo funciona si funciona para usted. Las pruebas estatales aún representan el 90% de todas las pruebas unitarias que escribimos, y somos muy conscientes de BDD en nuestro equipo.

Haz lo que funcione mejor para ti.

Un par de cosas.

Primero, cuando hace cosas como TDD para que su código sea comprobable, termina con una clase más pequeña. Si tiene una clase con muchas propiedades privadas que no puede inspeccionar, hay una buena posibilidad de que pueda dividirse en múltiples clases y hacer más comprobable.

En segundo lugar, la arquitectura OO de OldSchool intenta hacer que el software sea seguro mediante el uso de salvaguardas del lenguaje para evitar que las cosas sean accesibles. Una arquitectura TDD hace que el software sea más robusto al escribir pruebas que verifiquen lo que realmente hace el código, poniendo menos énfasis en el uso de construcciones de lenguaje para garantizar lo que el programa no hace.

Por último, verificar una propiedad no es la única forma de validar el código hizo lo que se suponía que debía hacer. El libro XUNIT Patrones de diseño documenta otros enfoques aquí: http://xunitpatterns.com/Result%20verification%20patterns.html

Llamo a los métodos de entrada pública de un sistema (es decir, presiono los datos de entrada al sistema), y luego obtengo (y afirmo) la salida del sistema. No estoy probando el estado interno del sistema, sino su comportamiento público/visible: ¿Debería uno probar la implementación interna o solo probar el comportamiento público?

Lo que mencionas se llama pruebas de estado. También hay pruebas de comportamiento. Las técnicas utilizadas para la inyección de dependencia, la inversión de control y la burla:

Todos los efectos secundarios de su clase se implementan como invocaciones del método en sus "dependencias", es decir, objetos suministrados desde el exterior, generalmente en el constructor. Luego, en su prueba de unidad, suministra un objeto falso en lugar de uno real. El objeto falso puede recordar si se llamó a su cierto método, y eso es lo que afirma en su prueba.

Existen un número de marcos de burla que automatizan la creación de objetos simulados mediante la generación dinámica de clases que implementan una interfaz dada. Los más populares son Rhino.Mocks y Moq.

Hola Justin, como tú, recientemente estaba pensando en agregar Getters a mi objeto de dominio de escritura solo en aras de las pruebas unitarias, pero ahora estoy convencido de que me equivocó. Suponiendo que haya comprado la idea de un dominio de escritura en primer lugar, entonces si tiene obteniendo, está pidiendo problemas. El principio de dominio de escritura solo querría que dispare un evento desde su objeto de dominio, o lea de una proyección que escribió su objeto de dominio, o algo así. Una vez que expone a los obtentadores, está comenzando a exponer la "forma" del objeto y, como dice Greg Young, "los objetos de dominio tienen comportamiento, no forma".

Dicho esto, estoy luchando con su misma pregunta ... ¿Cómo se une a prueba un objeto de dominio de escritura? Aquí está mi plan actual: estoy pensando en hacer que mi objeto de dominio dispare un evento de dominio que diga "estas propiedades cambiaron", y en mi prueba unitaria, me registraré antes de enviar el "EditCommand". Echa un vistazo a la publicación de Udi Dahan en eventos de dominio aquí, y también ver Lo que Eric Evans dice sobre eventos de dominio.

Me preguntaba lo mismo hasta que finalmente encontré los siguientes artículos.Encontré que eran excelentes manuales para realizar la verificación del comportamiento, especialmente el primero que me brindó varios "momentos ajá":

  1. Uso de simulacros y pruebas para diseñar objetos basados ​​en roles
  2. Roles simulados, no objetos
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top