How do you like your Mocks served?
I like them refreshing, of course:
Mockito is the new Java mock library on the block, with lots of interesting features. It replaced JMock in almost all my Java projects, mainly because:- the syntax produces_ clear and readable test code_ (see below for an example), because it doesn’t abuse of anonymous class and methods are really methods.
- stub and verification happens logically, and at different place
- no replay or framework control methods ala EasyMock
- fully integrated to Junit (using @RunWith for instance)
- helpful annotations to create mock automagically
- it promotes simple tests by nature (and that’s essential to my eyes)
Basically, you can only do two things with Mockito:
- stub, or
- verify :-)
Enough discussion, let’s focus on an example:
@Test
public void itShouldComputeAndSetThePlayerRank()
{
// creating a mock from an interface
// is as easy as that:
Player p = mock(Player.class)
// stub a method
when(p.getScore()).thenReturn(5);
// our imaginary SUT
ELOCalculator.computeRank(p);
// let's verify our rank has been computed
verify(p).setRank(12);
}
Due to its use of Generics and Java 5 autoboxing, the syntax is very clean, clear and readable. But that’s not all, Mockito provide a Junit 4 runner that simplifies mock creation with the help of annotations:
@RunWith(MockitoJUnit44Runner.class)
public class OurImaginaryTestCase
{
@Mock
private Player player;
@Test
public void playerShouldBeRanked()
{
// we can use player directly here,
// it is mocked to the Player Interface
}
}
Of course during the verification phase of the test you can check for
- the number of calls (or check for no calls at all)
- the arguments (Mockito defines lots of useful arguments matcher, and you can plug any Hamcrest matchers),
- the call order,
- and for stubbing, you can also throw exception, return values, or define callbacks that will be called when a return value is needed.
In a word it’s really powerful. It is also possible to spy on concrete objects however as the manual says this is not partial mocking:
so you can’t use this method to check that the method under test calls other methods of the same object.Here’s an example of what I mean (the following test passes):
public class RealObject
{
public int a()
{
return 10;
}
public int b()
{
return 20 + a();
}
}
@Test
public final void test1()
{
RealObject real = new RealObject();
RealObject spy = spy(real);
when(spy.a()).thenReturn(12);
// notice the 30 here
assertThat(spy.b(), equalTo(30));
}
See Mockito author’s last blog post about the subject or this mockito mailing list post.
Basically the code should be refactored or we could use a subclass to overcome this.
There is also a debate about stubbing and verifying (the same call). Usually you don’t want to do that. Stubbing should be enough, if your code succeed then the call was implicitly verified. So usually if you stub there is no need to verify, and if you verify you don’t need to stub (except if you need to return something critical to the rest of the code, in which case you don’t need verification). Once again, Mockito’s author has a great post on the_stubbing or verifying debate_.
Of course if you are an Eclipse user, do not forget to add to the list of Favorites all Mockito static import, so that Content Assist knows all the matchers.
Happy unit testing with Mockito :-)
Comments