c# tdd domain-driven-design encapsulation getter

c# - TDD, DDD y encapsulación



domain-driven-design encapsulation (8)

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 mejor manera, recientemente he estado leyendo sobre TDD y DDD y creo que los principios y las prácticas serían una Ideal para 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 asegurar 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 mediante la eliminación de todos los "captadores".

Por lo 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 dude en llamarme idiota e iluminarme; cualquier orientación sería muy apreciada.


Hola, Justin, como usted, recientemente pensé en agregar captadores a mi objeto de dominio de solo escritura por el bien de las pruebas de unidad, pero ahora estoy convencido de que estaba equivocado. Suponiendo que se haya comprometido con la idea de un dominio de solo escritura en primer lugar, si tiene getters, está buscando problemas. El principio de dominio de solo escritura querría que dispares un evento desde el objeto de tu dominio, o que lo leas desde una proyección que escribió el objeto de tu dominio, o algo así. Una vez que expones a los captadores, empiezas a exponer la "forma" del objeto, y como dice Greg Young, "los objetos de dominio tienen un comportamiento, no una forma".

Dicho esto, estoy luchando con su misma pregunta ... ¿cómo prueba en unidad un objeto de dominio de solo 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 de unidad, me registraré antes de enviar el "EditCommand". Echa un vistazo a la publicación de Udi Dahan sobre los Eventos de Dominio here , y también ve lo que Eric Evans dice acerca de los Eventos de Dominio .



Lo que estás describiendo es la verificación del estado en el que afirmas 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, a qué métodos no se llama.

Mira en este artículo de Martin Fowler para más detalles: Mocks Aren''t Stubs .


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

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

Existe una cantidad de Mocking Frameworks que automatizan la creación de objetos simulados generando dinámicamente clases que implementan una interfaz determinada. Los más populares son Rhino.Mocks y Moq.



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

Pero cuando desea probar los modelos CQRS, puede hacer afirmaciones sobre los eventos de dominio activados 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 CustomerRename pendiente con el valor "Foo" en su almacén de eventos pendientes. (en su lista o en la lista de eventos de su entidad dependiendo de la implementación)


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

En la práctica, he encontrado que el BDD es más frágil en muchos casos que solo pruebas de estado. Si bien algunas personas pueden exigir cierta 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 del BDD en nuestro equipo.

Haz lo que funcione mejor para ti.


Un par de cosas.

Primero, cuando haces cosas como TDD para hacer que tu código sea verificable, terminas 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 se pueda dividir en varias clases y que sea más comprobable.

En segundo lugar, la arquitectura OO de la vieja escuela trata de 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 verifican 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, la verificación de una propiedad no es la única forma de validar el código haciendo lo que se suponía que debía hacer. El libro xUnit Design Patterns documenta otros enfoques aquí: http://xunitpatterns.com/Result%20Verification%20Patterns.html