« Guice 1.0 vs 2.0 | Main | Who supported prop 8 »
Thursday
Jan222009

JMock vs EasyMock Smackdown

Lets see which of the two popular Java test object mocking tools is more straightforward. Cast your vote! (in comments)

with jMock
with EasyMock
you need to import

import org.jmock.Expectations;import static org.easymock.classextension.
EasyMock.createMock;
import static org.easymock.classextension.
EasyMock.expect;
import static org.easymock.classextension.
EasyMock.expectLastCall;
import static org.easymock.classextension.
EasyMock.replay;
import static org.easymock.classextension.
EasyMock.verify;
your test class needs to extend

MockObjectTestCaseTestCase
in setUp() method

mockedThing = mock(SomeInterface.class)mockedThing = createMock(SomeInterface.class)
to set expectations
checking(
new Expectations() {{
// this run does not throw
one(mockedThing).run();

// expect an exception
one(mockedThing).run();
will(throwException(new RuntimeException());

// expect multiple runs
exactly(4).of(mockedThing).getBlah();
}});

// since run() returns void
expect(mockedThing.run());

// or if the method returns non-void
expect(mockedThing.execute(SOMETHING))
.andReturns(SOMETHING_ELSE);

// expect an exception
mockedThing.run();expectLastCall().times(1).

andThrow(new RuntimeException());

// expect multiple runs
mockedThing.run();expectLastCall().times(1);

to put into replay mode

N/A
replay(mockedThing);
// only after this call the mock is usable
to use the mock in tests

RealThing realThing = new RealThing(mockedThing);

// this will call the mocked thing at some point
realThing.doSomething();

RealThing realThing = new RealThing(mockedThing);

// this will call the mocked thing at some point
realThing.doSomething();

to verify mock

N/A
verify(mockedThing);
// if you forget this, you will not know if the
// expectations were fulfilled
thread safe

???
mockedThing is not thread-safe.... use this
to make it so:
makeThreadSafe(mockedThing, true);

EmailEmail Article to Friend

Reader Comments (5)

I vote for jMock. I hate the modal API of EasyMock, where it's all too easy to forget to put a mock in playback mode. Sure, jMock has some odd syntax, but it reads well once written.

January 26, 2009 | Unregistered CommenterPeter

Regarding your first comparison, why not just import all of the classextensions?

import static org.easymock.classextension.
EasyMock.*

March 14, 2009 | Unregistered Commenterpatient renter

I should also mention - this is all moot since Mockito is a better alternative to both frameworks mentioned here :) Check it out if you haven't yet.

March 15, 2009 | Unregistered Commenterpatient renter

I vote for EasyMock. The reason is the syntax is easier than JMock.

When you work in a large team with members at different levels. Choosing EasyMock is more reasonable.

April 4, 2010 | Unregistered CommenterThang

As patient renter said, static import EasyMock.* instead of every method you will use (I find test cases specific enough domains to static import Asserts.* and EasyMock.* without having any confusion).

expect(someVoidMethod()) won't compile. You just have to call into your mocks for void methods.

In EasyMock, it's easier to understand if you think about how it works:

1. Call some methods into the proxy you created with createMock.
2. Perhaps define some things for those methods to return/throw.
3. replay [you're finished training it]
4. Call the code to test
5. verify [verify that what you expected happened in the proxy]

If you break down the order that things are happening in an EasyMock example, it becomes clearer when and why you need expectLastCall().

expect(myMock.add(1,2)).andReturn(3);
replay();
toTest.doSomething();
verify();

translates to:

1. call add method on myMock
2. call EasyMock.expect(T) [T is the return type of your add method]
3. call IExpectationSetters.andReturn(T)
4. call EasyMock.replay()
5. call your code to test
6. call EasyMock.verify()

As you can see, expect(myMock.add(1,2)).andReturn(3) is just a fancy way of writing:

myMock.add(1,2);
expect(0).andReturn(3); //The 0 is arbitrary, what is important is that it is the correct type (int/Integer in our case)

Well, what happens when we have a void method?
expect(myMock.voidMethod());

Uh-oh, nothing to return to be a parameter for our expect.

Well, if we don't need to throw an exception, just call the void method and we'll still correctly train our mock.

myMock.voidMethod();

But if we need our mock to throw an exception?

expect(myMock.divide(1,0)).andThrow(new ArithmeticException()); //This works

expect(myMock.voidMethod()).andThrow(new RuntimeException()); //This does not work, again, no return value to be expect's parameter

THAT is why we need expectLastCall()

myMock.voidMethod();
expectLastCall().andThrow(new RuntimeException());

June 18, 2010 | Unregistered CommenterJohn

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>