Why Mockito beats Easymock & co.

Unit testing your application is the key to develop a good piece of software.
Mocking is the key to write good unit tests.
Mockito is the key that opens the door to a way of mocking that has never been so simple and elegant.

Let's take a look at two different versions of the same unit test, the first uses easymock while the second is based on mockito.

EasyMock version:

public void testMethod() throws Exception {
 
   Collaborator mock=createMock(Collaborator.class) ;
 
   ClassToTest testedObject = new ClassToTest();
 
   testedObject.setCollaborator(mock);
 
   expect(mock.someService()).andReturn("output");
 
   mock.someOtherService();
 
   replay(mock);
 
   testedObject.method()
 
   verify(mock);
 
}

Mockito version:

public void testMethod() throws Exception {
 
   Collaborator mock=mock(Collaborator.class) ;
 
   ClassToTest testedObject = new ClassToTest();
 
   testedObject.setCollaborator(mock);
 
   when(mock.someService()).andReturn("output");
 
   testedObject.method();
 
   verify(mock).someOtherService();
 
}

With easymock:

* you need to know that first you have to declare what are the methods that have to be invoked on your mock and which outputs they have to return
* you need to know that before your mock really mocks you have to make a call to replay
* you need to know that if you want to verify the mock's method invocations declared earlier a call to verify is necessary.

With mockito:

* the code tells you that when the service() method is called then "output" is returned
* the code tells you that after the method under test is run a call to someOtherService() has to be verified

The degree of readability of these two implementations says a lot about how nice Mockito is.
Suppose you are studying about how to mock you will probably understand the second example without even studying Mockito, while the same cannot be said for the first example.

Mockito differs from the rest because it distinguishes between the concept of stubbing and verify.
Verifying the invocation to a stubbed method is not really important while usually it's more important to test if the stubbed value is used correctly rather than where it comes from.

But it is not finished here! A lot of other nice features are available:

* with just an annotation you can mock whatever you want, even concrete classes!
* thanks to the hamcrest support you can easily specify in which condition your mock has to return a certain output or something else
* you can also specify how many times you expect a certain method to be called (or that it has not been called at all)
* you can even add logic to your stubbed implementation thanks to the doAnswer method

Just one last tip: if your test is not running as expected you are probably not stubbing enough!
The default implementation of all the methods of a mock return null, if inside the method under test you call a stubbed method using the output of some other method of the mock (that has not been stubbed) than you are passing null as input to the stubbed method.
A declaration like this:
when(mock.method(any(Input.class))).thenReturn(new Object());
will not match your input (null) and will return null as well ;)

Trackback URL for this post:

http://www.func.nl/trackback/111

typo's

- "Mocking is the key to write good unit *tests*"
- "thanReturn" should be "thenReturn".

Nice article, although I would not have chosen to present an opinion as fact (to prevent mocking framework fundamentalist wars) :)

typo's

Thanks for both corrections and feedback :)

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]".