I want to be clear up front: I’m a big fan of Mockito. It’s very easy to use, and quite powerful. It has saved me a ton of time when writing unit tests. With that said, I’m going to grumble about it for most of this post.

My main gripe with Mockito is it plays fast and loose with naming conventions for test doubles. The terminology we use for test doubles can get a bit muddled at the best of times, and Mockito pretty much stomps all over it.

Test doubles

You might be asking “what are test doubles?” You might know them as “mocks” or “stubs”. (This is actually part of the problem, as we’ll see.) We can define a test double as any object we substitute for a production object, for testing purposes.

That definition is pretty vague. Most of my test doubles just return some fixed values - can’t we have a specific name for those? What about ones that record interactions? In his book XUnit Test Patterns, Gerard Meszaros did us all a favour and came up with 5 different categories. Briefly, they are:

  • Stubs provide predefined (“canned”) responses to method calls, returning a value or throwing an exception.
  • Spies are stubs that record their interactions, for later verification.
  • Dummies are placeholders which are used only to satisfy method/constructor parameters. The code being tested shouldn’t actually interact with the dummy.
  • Mocks are configured with a set of expected interactions, which are verified later.
  • Fakes are different from other test doubles in that they actually implement real behaviour, albeit in a simplified form.

This was a step forward, and it became popular with the help of people like Martin Fowler - see his famous article mocks aren’t stubs. This gave us all a common vocabulary to use to talk about this stuff.

Mockito

So, along comes Mockito, which gives us 2 methods (and 2 matching annotations) for creating test doubles:

  1. Mockito.mock() or @Mock When you call Mockito.mock(Thing.class), Mockito generates a subclass of Thing (or an implementing class if Thing is an interface) on the fly, and returns an instance of that class. Depending on what you then do to that instance, it can be used as a stub, a spy, a dummy, or a mock.
  2. Mockito.spy() or @Spy The difference with Mockito.mock() is that rather than using default return values and having no behaviour, the default behaviour here is to delegate to thing (or an instance of the class if thing is an instance of Class). You get the behaviour of thing, with the ability to record any interactions with it and provide override methods with stubbed implementations. The normal term for this sort of test double is a partial test double. (Some people call them partial mocks, but I obviously take issue with that!)

Is this really that big a deal?

Names are powerful. Using clear, accurate names helps others immediately latch onto concepts - they provide mental shortcuts we can all share. It’s jargon, and we can infer its value from the fact we see it used everywhere.

As an example, look at design patterns. They encapsulate complicated concepts into simple names. If you see a class called UrlFactory you can immediately guess at how it works. If I say “X just delegates to an instance of Y”, you immediately know what I’m talking about.

If we use overly-vague names, we don’t get to take any of those mental shortcuts. Imagine trying to describe OO programming to someone without using the words “class”, or “object”. It would be really hard! You’d probably end up coming up with new names for those concepts.

Now imagine someone explaining OO programming to you, but they keep mixing up those terms. That’s even worse! This is what Mockito is doing.

Examples

Let’s look at some examples. You’ll see that Mockito doesn’t differentiate between the different types based on name - you have to look at how the objects are used to work out which type of double they are.

Mocks

A simple test using a mock in Mockito goes something like this:

// ARRANGE
// Throw an exception for any unexpected interactions, by specifying a default answer.
Thing mockThing = mock(Thing.class, new Answer<Object>() {
  @Override public Object answer(InvocationOnMock invocation) throws Throwable {
    throw new RuntimeException("Unexpected interaction!");
  }
});

// Set up expected interactions.
when(mockThing.getString()).thenReturn("result");

// ACT...

// ASSERT
// Verify expected methods were called.
verify(mockThing).getString();

Side note: Notice that we have to explicitly call verify() for the same methods that we set up expectations for at the beginning. There’s no verifyOnlyExpected() method. It turns out, Mockito’s support for mocks isn’t actually that great!

Spies

Another simple test:

// ARRANGE
Thing spyThing = mock(Thing.class);

// Override default method stub.
when(spyThing.getString()).thenReturn("result");

// ACT...

// ASSERT
// Verify expected methods were called.
verify(spyThing).getString();
verifyNoMoreInteractions(spyThing);

The only thing which changed here is that we don’t specify a default answer. (On a side note, I hope you find the spy = mock() bit in the first line as jarring as I do.)

Stubs

Another simple test:

// ARRANGE
Thing stubThing = mock(Thing.class);

// Override default method stub.
when(stubThing.getString()).thenReturn("result");

// ACT, ASSERT...

Look familiar? Same as the spy, but we lost the verification at the end.

The manual approach

I feel obliged to point out that it should generally be as easy, or easier, to write stubs manually than it is to use Mockito. If you find yourself using Mockito to stub a class because it has 10 methods and your test only cares about 2 of them, then that’s a code smell. You might want to split up the class, or at least define separate interfaces for different bits of behaviour.

Dummies

Dummies are really simple:

// ARRANGE
Thing dummyThing = mock(Thing.class, new Answer<Object>() {
  @Override public Object answer(InvocationOnMock invocation) throws Throwable {
    throw new RuntimeException("Unexpected interaction!");
  }
});

// ACT, ASSERT...

This is the same as the mock, but without setting up or validating any expected interactions.

What about Mockito.spy()

I mentioned this earlier, but it bears repeating: Mockito.spy() gives you something commonly referred to as a partial test double. It can function as a partial mock, a partial spy, or a partial stub. (Partial dummies don’t really make sense, for hopefully obvious reasons.)

The use of partial mocks is almost always a code smell, but they can be a useful stopgap when working with legacy code.

A simple test with a partial test double might look like this:

// ARRANGE
Thing partialMockThing = spy(new Thing("result"));

// ACT...

// ASSERT
// Verify expected methods were called.
verify(partialMockThing).getString();
verifyNoMoreInteractions(partialMockThing);

A case for the defence?

I’m not a mind reader, so I don’t know what the exact thought processes that led to Mockito functioning the way it does. I can suggest some possibilities though:

  • Software development is full of trade-offs, and we cope with this by prioritising certain features over others. In this case, the developers may have valued simplicity (of API and implementation) over precision.
  • The developers may have felt that the terminology established by Meszaros wasn’t worth following - maybe they felt it wasn’t ubiquitous enough, or maybe they thought it was undermined by the existing confusion between mocks, stubs and test doubles.
  • The really liked their pun on “mock”, but couldn’t come up with good ones for “spy” and “stub”. ;)

Conclusion

The first thing I said was that I’m a big fan of Mockito, and I am. I think you should be, too! But I don’t think it’s perfect. Names matter, and Mockito breeds confusion where it could bring clarity.

If you’ve never heard of test doubles, I hope this has been a good introduction. Even if you had heard of them before, I hope this post has been food for thought. (Especially if you happen to be one of the maintainers of Mockito!)