12

After reading a few articles about Newable vs Injectable objects and how these concepts relate to DDD's services, entities and value objects, I was left with some doubts about using newables in my code especially in my unit tests.

Main candidates for newables were Entities and Value objects meaning that instead of injecting these dependencies into other objects one should just new an instance of these objects and use them directly in the code.

However, good DDD practices advocate assigning responsibilities to entities and value objects if they were deemed appropriate. So the entities and value objects will end having some serious business logic in them.

Now if a service operates on an entity or a value object should I mock the entity or value object and pass the mock to the service (mocking will require an interface for the value objects or entities which seems to be advocated against) ?

Or should I just new an entity/value object and pass a concrete implementation to the service and thus violating the unit testing principle of testing only one unit?

7
  • Related: stackoverflow.com/q/2833422 Commented Jul 22, 2013 at 22:17
  • It depends if you're a classical or a mockist tester: martinfowler.com/articles/mocksArentStubs.html
    – jhewlett
    Commented Jul 23, 2013 at 0:33
  • @jhewlett A classicist would not mock anything; a mockist would most likely only mock Services, Repositories, and Factories (which are "injectables"), never Entities or Value Objects (which are "newables").
    – Rogério
    Commented Sep 14, 2016 at 16:41
  • @Rogério, when you say Services; do you mean Application Services or Domain Services?
    – w0051977
    Commented Jan 24, 2018 at 20:08
  • @Songo, what did you decide on? Do you mock: Entities; Value Objects and Domain Services?
    – w0051977
    Commented Jan 24, 2018 at 20:09

2 Answers 2

14

I'm reading that you're of the opinion that unit tests, much like SOLID objects, must have "one reason to break". It's a noble goal, but I think you'll find that in many cases it is simply not feasible. One of those cases is here, where you have a "rich" domain object (DDD differentiates between Entities and Value Objects, which both comprise the "domain model") that is a dependency of the system under test.

In these situations, I have the philosophy that, given the domain object has its own comprehensive unit test coverage, trusting that the object will work as designed in a unit test for a different SUT does not necessarily violate the unit test. If this test were to break because of a breaking change to the domain, then I would expect the domain object's unit test to break as well, leading me toward something to investigate. If the domain object's unit test had been updated properly as a red test, then made green with the change, and this other test then failed, that's not necessarily a bad thing either; it means that the expectations of this other test conflict with the new expectations for the domain, and I need to make sure both of them agree with each other and the overarching acceptance criteria of the system.

As such, I would only mock a domain object if said domain object produced "side effects" that were undesirable from a unit-testing perspective (i.e. touching external resources like data stores), or if the logic of the domain object were sufficiently complex that placing it in the proper state for the test becomes a roadblock to defining and passing the test.

That then becomes the driving question; which is easier? To use the domain object for its intended purpose within the test, or to mock it? Do whichever is easier, until it's no longer the easier option, such as when a functional change breaks the test of the service in a complex way; if this happens, then rewrite the test to produce a mock that exposes the functional requirements depended on by the service, without the complexity that breaks it.

Understand that either way, there should be an integration test that uses the real domain object plugged into the real service that tests the interaction between these two at a higher level of abstraction (such as testing, for instance, not only the functionality behind a service endpoint, but a proxy across which the domain object is serialized and sent).

1
  • In DDD, the "domain model" also includes Domain Services, Repositories, and Factories, not just Entities and Value Objects.
    – Rogério
    Commented Sep 14, 2016 at 16:38
0

Trusting the dependent class that it works properly, hoping there would fail some unit tests when something there does not work, then it should this be tested very vell. Maybe there are missing some important unit tests? There can be an untested case that would create an error, that will be produced in my originary testing class, and would not be catched in the dependent class itself.

So in my opinion for unit tests, dependent classes should be mocked. If not doing so, then its an integrational test.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.