Using EasyMock or Mockito

I have been using EasyMock for most of time but recently I worked with a few people who were pretty much inclined to use Mockito.

Not intending to use two frameworks for the same purpose in the same project I adopted Mockito.

So for the last couple of months I have been using Mockito and here is my comparative analysis of the two.

The people with whom I have work cite reasons of test readability for using Mockitio but I have a different opinion on the same. Suppose we have the following code that we intend to test :
public class MyApp {
    MyService service;
    OtherService otherService;

    void operationOne() {
        service.operationOne();
    }

    void operationTwo(String args) {
        String operationTwo = otherService.operationTwo(args);
        otherService.operationThree(operationTwo);
    }

    void operationThree() {
        service.operationOne();
        otherService.operationThree("success");
    }
}

class MyService {
    void operationOne() {}
}

class OtherService {
    public String operationTwo(String args) {
        return args;
    }

    public void operationThree(String operationTwo) {}
}

Now let me write a simple test case for this class using EasyMock and the using Mockito.

 public class MyAppEasyMockTest {
    MyApp app;
    MyService service;
    OtherService otherService;

    @Before
    public void initialize() {
        service = EasyMock.createMock(MyService.class);
        otherService = EasyMock.createMock(OtherService.class);
        app = new MyApp();
        app.service = service;
        app.otherService = otherService;
    }

    @Test
    public void verifySimpleCall() {
        service.operationOne();
        EasyMock.replay(service);
        app.operationOne();
        EasyMock.verify(service);
    }
 }
public class MyAppMockitoTest {
    MyApp app;
    MyService service;
    OtherService otherService;

    @Before
    public void initialize() {
        service = Mockito.mock(MyService.class);
        otherService = Mockito.mock(OtherService.class);
        app = new MyApp();
        app.service = service;
        app.otherService = otherService;
    }

    @Test
    public void verifySimpleCall() {
        app.operationOne();
        Mockito.verify(service).operationOne();
    }
 }
This is a really simple test and I must say the Mockito one is more readable . But according to the classic testing methodology the Mockito test is not complete. We have verified the call that we are looking for but if tomorrow I change the source code by adding one more call to service the test would not break.
 void operationOne() {
        service.operationOne();
        service.someOtherOp();
  }
Now this makes me feel that the tests are not good enough. But thankfully Mockito gives the verifyNoMoreInteractions that can be used to complete the test. Now let me write a few more test for the MyApp class.
public class MyAppEasyMockTest {
      @Test
    public void verifyMultipleCalls() {
        String args = "one";
        EasyMock.expect(otherService.operationTwo(args)).andReturn(args);
        otherService.operationThree(args);
        EasyMock.replay(otherService);
        app.operationTwo(args);
        EasyMock.verify(otherService);
    }

    @Test(expected = RuntimeException.class)
    public void verifyException() {
        service.operationOne();
        EasyMock.expectLastCall().andThrow(new RuntimeException());
        EasyMock.replay(service);
        app.operationOne();
    }

    @Test
    public void captureArguments() {
        Capture<String> captured = new Capture<String>();
        service.operationOne();
        otherService.operationThree(EasyMock.capture(captured));
        EasyMock.replay(service, otherService);
        app.operationThree();
        EasyMock.verify(service, otherService);
        assertTrue(captured.getValue().contains("success"));
    }

}

public class MyAppMockitoTest {
    @Test
    public void verifyMultipleCalls() {
        String args = "one";
        Mockito.when(otherService.operationTwo(args)).thenReturn(args);
        app.operationTwo(args);
        Mockito.verify(otherService).operationTwo(args);
        Mockito.verify(otherService).operationThree(args);
        Mockito.verifyNoMoreInteractions(otherService);
        Mockito.verifyZeroInteractions(service);
    }

    @Test(expected = RuntimeException.class)
    public void verifyException() {
        Mockito.doThrow(new RuntimeException()).when(service).operationOne();
        app.operationOne();
    }

    @Test
    public void captureArguments() {
        app.operationThree();
        ArgumentCaptor capturedArgs = ArgumentCaptor
                .forClass(String.class);
        Mockito.verify(service).operationOne();
        Mockito.verify(otherService).operationThree(capturedArgs.capture());
        assertTrue(capturedArgs.getValue().contains("success"));
        Mockito.verifyNoMoreInteractions(service, otherService);
    }
}
These are some practical scenarios of testing where we would like to assert arguments, Exceptions etc. If I look and compare the ones written using EasyMock with the ones using Mockito I tend to feel that both the tests are equal in readability, none of them do a better task.
The large number of expect and return calls in EasyMock make the tests not readable and the verify statements of Mockito often compromise over test readility. As per the documentation of Mockito the verifyZeroInteractions, verifyNoMoreInteractions should not be used in every test that you write but if I leave them out of my tests then my tests are not good enough.
Moreover in tests everything thing should be under the control of the developer i.e. how the interaction are happening and what interactions are happening. In EasyMock this aspect is more visible as the devloper must put down all of these interaction in his code but in Mockito, the framework takes care of all interactions and the developer is just concerned with their verification ( if any). But this can lead to testing scenarios where the developer is not under control of all interactions.
There are few nice things that Mockito has like the JunitRunner that can be used to create Mocks of all the required dependencies. It is a nice way of removing some of the infrastructure code and EasyMock should also have one.
@RunWith(MockitoJUnitRunner.class)
public class MyAppMockitoTest {
    MyApp app;
    @Mock
    MyService service;
    @Mock
    OtherService otherService;

    @Before
    public void initialize() {
        app = new MyApp();
        app.service = service;
        app.otherService = otherService;
    }
}
Conclusion:
Since I have used both frameworks, I feel that except for simple test cases both EasyMock and Mockito lead to test cases that equal in readability. But EasyMock is better for the unit testing as it forces the developer to take control of things. Mockito due to its assumptions and considerations hides this control under the carpet and thus is not a good choice. But Mockito offers certaing things that are quite useful(eg. junitRunner, call chaining) and EasyMock should have one in its next release.

Reference: using EasyMock or Mockito from our JCG partner Rahul Sharma at the The road so far… blog blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


seven × 3 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close