Continue Discussion 18 replies
October 2010

jhannes

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.

1 reply
October 2010

Szczepiq

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 :)

1 reply
October 2010 ▶ jhannes

jbrains

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!

October 2010 ▶ Szczepiq

jbrains

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.

October 2010

jbrains

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.

April 2012

Vinay

Concise & precise!

June 2013

Patrick

clear and therefore convincing, well done!

November 2013

carlosble

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? :-)

1 reply
November 2013 ▶ carlosble

jbrains

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.

1 reply
November 2013 ▶ jbrains

carlosble

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

May 2014

fletcherr

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.

1 reply
May 2014

romaingervais

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.

1 reply
May 2014 ▶ fletcherr

jbrains

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.

May 2014 ▶ romaingervais

jbrains

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". :)

March 2017

carlosble

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

2 replies
June 2017 ▶ carlosble

jbrains

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.

June 2017 ▶ carlosble

jbrains

I think I might have fixed it!

1 reply
June 2017 ▶ jbrains

carlosble

Sweet! thank you!