Return the same object that was given as parameter with EasyMock

Every time I have to use EasyMock, I get annoyed. For those who don’t know EasyMock, it is a mocking framework that allows you to mock certain pieces of code when doing unit testing. In my humble opinion, there are better ways to create mocks in unit test, but at my current project I’m using EasyMock.
There are 2 reason, the first is the lack of more advanced mocking tutorials on the interwebs. When I go looking for a specific solution, I never really find what I need.
The second reason is a more justified one, but still personal. I alway forget how the API of EasyMock works, it is not self explanatory, a former colleague of mine even once called it DifficultMock…
I’m not going to rant about my lack of love for this java mocking framework, instead I’m going to offer a solution.
So basically, what I was trying to do, was to capture an argument I give to a method and return the same object. We could take the JPA method EntityManager.merge(T entity) method as example. We take an unattached object and attach it. The result is our attached object. Seems releasable to include in a test.
So I want to capture my argument and return it. After playing a bit with the API I got this

EntityManager entityManager = EasyMock.createNiceMock(EntityManager.class);
final Capture<Entity> capture = new Capture<Entity>();
EasyMock.expect(entityManager.merge(EasyMock.capture(capture))).andReturn(capture.getValue());
replay(entityManager);
executeTest();

This compiled fine, but gave an error at runtime, saying

Nothing captured yet

So I’m not able to define my andReturn method, because it already tries get the value of my captured object. Instead of giving my andReturn method a value, I have to give it a function, a closure. Since Java doesn’t have closures (yet), I’m forced to use a poor mans closure.
EasyMock supplies an Interface and a method we can use here. The IAnwser interface and we replace the andReturn method by the andAnwser method.
By creating an annonymous implementation of this interface, we create a one-function class, like a normal closure.

final EntityManager entityManager = EasyMock.createNiceMock(EntityManager.class);
final Capture<Entity> capture = new Capture<Entity>();
EasyMock.expect(entityManager.merge(EasyMock.capture(capture))).andAnswer(new IAnswer<Entity>() {

    public Entity answer() throws Throwable {
        return capture.getValue();
    }
});
replay(entityManager);

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>