Mockito Best Practices

You have picked up Mockito and you are interested in some good practices to avoid hangovers.

Don’t mix with Spring Integration Test

Mixing spring integration test and mockito can produce strange border effects like : singleton replaced by mocks,…
and will also lose the main benefit of mockito tests : speed !

Avoid abstract testcases

When something breaks it simply takes too long to diagnose.. An alternative is to create custom assertion and factory methods that can be reused.
-> prefer composition over inheritance.

Don’t mock your model

Prefer simply using your model

Campaign campaign = new Campaign();
campaign.setAssignee(office);
campaign.setType(PersonTypeCode.MEMBER);
campaign.setCreationUserLocation(office);
campaign.setOrganization("google");
campaign.calculateEndDate();

Over mocking it

Campaign mockCampaign = mock(Campaign.class);
when(mockCampaign.getAssignee()).thenReturn(office);
when(mockCampaign.getType()).thenReturn(PersonTypeCode.MEMBER);
when(mockCampaign.getCreationUserLocation()).thenReturn(office);
when(mockCampaign.getOrganization()).thenReturn("google");
when(mockCampaign.getCalculatedEndDate()).thenReturn(new DateMidnight());

Easier to read and you will may be add convenient contructor/factory methods to your production or test codebase… remember to put the code where it belongs.

Don’t abuse mocks

Mockito isn’t a Panacea. If all you have is a hammer, everything looks like a nail…

For example testing an xstream converter DescriptionTargetConverter

Don’t use mock, it requires more code… and you don’t really verify the output xml format (id,type,label)

    mockWriter = mock(HierarchicalStreamWriter.class);
    mockMarshalContext = mock(MarshallingContext.class);
    discriptionTargetConverter.marshal(mockTarget, mockWriter,mockMarshalContext);
    verify(mockWriter, times(3)).endNode();
    verify(mockWriter, times(3)).startNode(anyString());
    verify(mockWriter, times(3)).setValue(anyString());

It’s much more easy using xstream “as-is”

    comparaisonString= "<Target>  <id>3</id>  <type>" + type+ "</type>  <label>firstname lastname</label></Target>";
    XStream xstream = new XStream();
    xstream.registerConverter(discriptionTargetConverter);
    assertEquals(comparaisonString, StringUtils.replace(StringUtils.replace(xstream.toXML(target), "\n", ""), "\r", ""));

For more advanced xml assertion… check xmlunit

Don’t mock servlet api

The org.springframework.mock.web package contains a comprehensive set of Servlet API mock objects, targeted at usage with Spring’s Web MVC framework, which are useful for testing web contexts and controllers. These mock objects are generally more convenient to use than dynamic mock objects such as mockito.

Don’t replace asserts with verify

Taken from this article
The easiest methods to understand and test are methods that perform some sort of work. You run the method and then use asserts to make sure everything worked.
In contrast, mock objects make it easy to test delegation, which is when some object other than the SUT is doing work. Delegation means the method’s purpose is to produce a side-effect, not actually perform work. Side-effect code is sometimes needed, but often more difficult to understand and debug.

If your test code contains assert methods then you have a good test.
See for example the pmd rule for junit.

If it doesn’t contain asserts, and instead contains a long list of verify() calls, then you’re relying on side effects. This is a unit-test bad smell, especially if there are several objects than need to be verified. Verifying several objects at the end of a unit test is like saying, “My test method needs to do several things: x, y, and z.” The charter and responsibility of the method is no longer clear. This is a candidate for refactoring.

Finally “if it’s hard to…”

Junit and Mockito drive a fair amount of refactoring for me.

If it’s hard to read… it’s hard to test.
If it’s hard to test… it’s hard to use.
If it’s hard to test… you’re probably doing it wrong.
If it’s hard to test… take a look at the design and test it again !

Other mocking frameworks

Most of these rules should apply to other mocking frameworks like
Mockito,, Mockachino, , , JMockit , Unitils,…

About these ads

, ,

  1. #1 by bunkertor on July 10, 2012 - 1:16 pm

    Reblogged this on Agile Mobile Developer.

  2. #2 by Mathew Bukowicz on July 10, 2012 - 1:36 pm

    Great guide, very pragmatic approach. Thanks and keep up with the good woork!

  3. #3 by Łukasz Stachowiak on July 13, 2012 - 6:30 pm

    I think these are tips not only for Mockito, but for unit testing generally.
    Nice, thanks!

  1. Unit Testing | java7notes

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: