user1348997
user1348997

Reputation:

Mock Domain Entities in Unit Tests

I have a pretty simple question: I've been writing some Unit tests to a command object which has a Context object. This context has some domain entities inside of it.

    public class Context { 
          private DomainEntity domainEntity1;
          private Dto dto1;

          // getters and setters go here...

          public boolean isDomainEntityValid() {
              // a little bit of logic goes here
          }
    }

    public class Command {

          public void execute(Context context) { 
                // do its logic in here
          }
    }

The DTO and the DomainEntity have nothing but setters and getters and very simple validation methods (such as isFirstNameValid()).

The Context object does have logic in it - after all, it checks if the context is consistent, is the context is complete, and so on.

When unit testing the command object, it's pretty clear to me that the context should be mocked out - but what about the entity and dto? Should I mock them? If so, I'll have to do a lot of code like the one below

    doReturn(1L).when(domainEntity1).getId();
    doReturn("phil").when(domainEntity1).getName();

In the another words, a lot of behaviour for the getters methods will have to be defined.

So, bottom line: should I mock Domain Entities and DTOs when unit testing an object?

Upvotes: 2

Views: 2515

Answers (2)

Adrian Shum
Adrian Shum

Reputation: 40036

(I think I may elaborate a bit more on my comment)

Whether you need to do the mocking etc all depends on what's the logic in your System-Under-Test (SUT, in this case, your Command).

Whole idea of mocking/stubbing is we don't what our testing to SUT depends on other actual code. Therefore we make up the mocks/stubs which fit for use in test, so the validity of test only depends on SUT, but not other actual code (of course, given that your mock/stub is correctly written, but that's normally not a problem due to its simplicity)

So, if your logic of Command is something like

DomainEntity domain = context.getDomainEntity();
domain.doSomething();

then yes, you need to do the mocking for your domain entity.

However, if you are simply working against the context, like:

if (context.isDomainEntityValid()) {
    doSomething();
} else {
    doAnotherThing();
}

then there is no point to mock the domain entity.

One more thing to note, with help of mocking framework, you can simply do stubbing according to your SUT logic. You don't need to do stubbing for EVERY method.

Therefore, if your Command is only calling domain.doSomething(), just stub this method. Forget about DomainEntity#anotherMethod() DomainEntity#getId().

Upvotes: 0

Daniel Kaplan
Daniel Kaplan

Reputation: 67360

I think you're probably violating the "Law" of Demeter here. I put that in quotes because you shouldn't follow this as a law but as advice.

You're not really giving us enough context to be able to tell you what you should specifically change (ie: why does the command need the id and the name?), but there's this other principle called Tell, Don't Ask and I think if you change your code to follow that, your code will become much easier to test.

Upvotes: 2

Related Questions