JMock v. Mockito, but not to the death

Although I originally wrote this to describe how/when I use JMock compared to Mockito, you can easily read this as an article comparing the use of mocks (expectations) to the use of spies. JMock operates by default in “expectation” mode, while Mockito operates by default in “spy” mode. In short: expectations and spies have exactly the same expressive power and so I use both in different contexts.


This is a companion discussion topic for the original entry at http://blog.thecodewhisperer.com/permalink/jmock-v-mockito-but-not-to-the-death

I like the distinction between mocking new code and mocking legacy code. But I think both tools support both styles, so this is no reason to switch around the mocking tool.

For mockito: Mockito.verifyNoMoreInteractions(mocks)

This enforces that no accidental interactions at the same time as you get to put the verifications where they logically belong: With the other assertions.

I would wager that JMock has a converse setting, where you can turn off extra validations.

Personally, I found that quality developer does not tolerate accidental complexity regardless of the mocking tool. Similarly, poor developer codes a lot of accidental complexity even though he uses jMock. So at the end of a day I wanted to have a tool that helps me write clean, readable & less brittle tests with mocks. Hence I wrote mockito. Cool article :)

Yes; we don't need to switch tools, but I don't see the harm in using different tools for what they're most good at. I find some value in the separation.

Now I see how to use Mockito in the JMock style of "assume no-one should invoke it". I don't know whether one can use JMock in the Mockito style of "let anyone invoke it". I suppose Nat or Steve could comment and tell us!

Thank you for your kind words. I find that when I use test doubles, especially with expectations, and my tests become brittle, that I need to simplify my interfaces and my layers. For that, I prefer to have JMock put pressure on me to remind me to do that. I know the Java community benefits a lot from having Mockito, and now that I've seen how to use it effectively, so will I.

I would typically not as a strict framework (JMock) when I primarily want to stub, because I would feel tempted to setDefaultStub(null) (or whatever JMock 2 does) for virtually every test double. I find this in RSpec when I routinely invoke #as_null_object on test doubles. That duplication bothers me.

Concise & precise!

clear and therefore convincing, well done!

I find that spies make my tests less coupled to the implementation than mocks do. Mockito uses spies as the default test double whereas jMock uses mocks. A test should care about a single behavior and I like to make it explicit with the verification/assertion at the end. It's hard for me to think of examples where a mock is more suitable than a spy. Maybe for mission critical things like launching rockets? :-)

Spies don't check anything, so certainly by default, they can't create additional unexpected assertions.

When I use a mock (JMock mode), then I get feedback about my design. If I write a test that needs to call foo() and bar(), but doesn't want to check calling foo(), then why is foo() on the interface I'm talking to? Sometimes the answer is just to stub foo() (instead of checking the expectation) this one time and sometimes the answer is the separate foo() and bar().

This is not at all question of spy versus mock. If I stub every method on a mock, it becomes a spy. If I check every method call on a spy, it becomes a mock. Let's everyone stop arguing this point, please.

I like JMock mode (expectations by default) when I want to maximise feedback about my design, which usually happens when I test-drive new behavior. I like Mockito mode (stubs by default) when I already know that the design is terrible and I just want to add some tests right now, which usually happens when I work with legacy code. Simple.

I get your point J.B it's very interesting, thanks for the example. Holly examples! :-)

It's a great point about strictness.

On a tangent one thing I like about Mockito and Spock is that mock interactions are managed after the action. I much prefer the way the resulting test then reads – "when action x is taken, then the result is that method y of mock z is called". In the case of stubs the setup is done in advance of the action which also reads well – "given stub x will respond with y, when action z is taken, then…"

Spock has a fairly low ceremony strict mock as well where you simply add "0 * _" after any other interactions (meaning "zero calls to any method on any mock"). I appreciate it's low ceremony as opposed to zero ceremony, though.

When working with legacy code I think Powermock is even more appropriate than Mockito thanks to its ability to mock static methods and new operator.

Note also that Mockito lets you verify that your test just called the methods you verified :
--------------
Dependency1 dependency1 = Mockito.mock(Dependency1.class);
Dependency2 dependency2 = Mockito.mock(Dependency2.class);
ClassUnderTest classUnderTest = new ClassUnderTest(dependency1, dependency2 );

classUnderTest.doSomething();

Mockito.verify(dependency1).doSomethingElse();
Mockito.verify(dependency2).doAnotherThing();
Mockito.verifyNoMoreInteractions(dependency1, dependency2);
--------------

Another way of doing this would be to change the default behavior of a mock. You could easily make your test fail if a unstubbed method is called on a mock :
--------------
Dependency dependency= Mockito.mock(Dependency.class, new Answer<dependency>() {
....public Dependency answer(InvocationOnMock invocation) throws Throwable {
........throw new RuntimeException(invocation.getMethod().getName() + " is not stubbed");
....}
});

Mockito.doReturn(0).when(dependency).doSomething();

ClassUnderTest classUnderTest = new ClassUnderTest(dependency);

classUnderTest.doSomething();
--------------

This way you'll have to stub all the methods of "dependency" called during your test, otherwise your test will fail. Comment "doReturn..." to make the test fail.

I never used Jmock, so I don't make the comparison with Mockito. I just wanted to point out that Mockito can be more strict if you want it to.

Yes. I like the arrange-act-assert ordering of EasyMock and Mockito, but I got used to the JMock ordering fairly soon, so I no longer notice the cognitive load that it places on the programmer. I accept this in exchange for getting the default behavior that I (usually) prefer.

I don't mind having to write in Spock "and nothing else should happen", but before long, I'd want to push that duplication into the background, and the result would look like JMock anyway.

I agree. When adding tests to legacy code, I typically want more testing feedback at first, then design feedback second, hence this article: with legacy code I want to avoid too much design feedback early on, because I already know that the design needs a lot of work. At that stage, the details distract me more than they help me.

More to the point, though, I got tired of people saying that JMock was better than Mockito, or the reverse, or that spies are better than mocks, or the reverse. They're all the same, so teach each eir own. In this article I tried to describe "my own". :)

There used to be interesting comments to this post. I used to refer people to these comments. What happened man? Where are they? Thanks

I don't know. I can only guess that some migration failed sometime in the past six years. I'm trying to find the comments now.

I think I might have fixed it!

Sweet! thank you!