Imagine you have to mock a httpSession object, and you need to verify that some values are being added to the session attributes map during your method execution.

Well, EasyMock has an interesting ExpectationSetter method that helps with that task “andAnswer”.

andAnswer lets you create a response at the exact moment when a mocked method is invoked and by providing an implementation of the IAnswer interface, which includes a single method (answer).

Along with andAnswer, we can use a Capture object as a matcher to… capture an incoming value when our mock is invoked.

By combining both tools, we can :
1.- Capture an incoming value to the mocked method.
2.- Store the value to another object (like a Map)
3.- Create a returning object on the fly or throw an exception

Let’s see it in action:

public class MyTest {
    @Mock
    private HttpSession mockSession;
    Map<String, Object> sessionAttributes = new HashMap<>();
    private GameController controller;

    @Before
    public void setup() {
        controller = new GameController();
    }

    @Test
    public void testMyHttpSession() {
        Capture<String> stringCapture = new Capture<>();
        Capture<Object> objectCapture = new Capture<>();
        expect(mockSession.getAttribute(capture(stringCapture)))
                .andAnswer(() -> httpSessionAttributes.get(stringCapture.getValue())).anyTimes();
        mockSession.setAttribute(capture(stringCapture), capture(objectCapture));
        expectLastCall().andAnswer(() -> {
            httpSessionAttributes.put(stringCapture.getValue(), objectCapture);
            return null;
        });
        replayAll();

        String myData = "SomeDataHere";
        controller.storeMyObjectInSession("myKey", new Game(myData));

        verifyAll();

        // Let's add some assertions to ensure that GameController is storing our object
        Game actualValue = sessionAttributes.get("myKey");
        assertNotNull(actualValue, "Game object was not stored by GameController");
        assertEquals(myData, actualValue.getData(), "Unexpected data from the stored object");
    }
}

In the code block above, I’m creating a Map ( sessionAttributes ) that will store all the values that generally will be stored in the attributes map from the httpSession Object, which, as you can see, is a Mock.

For my test method, I create a couple of capture objects: the stringCapture that will contain the key used to add a new attribute to the HttpSession and an objectCapture that will hold the Object to be stored in the HttpSession attribute.
Notice the Capture class is generic so that we can capture a specific object like a String or just an Object.

Next, I set up the expected events, the getAttribute that will return a previously stored Object in the mocked httpSession, and the setAttribute that will add the incoming key/values to our sessionAttributes map. By adding expectLastCall after our void method setAttribute, we can add an answer to store the incoming data to our map.

In short, we’re emulating the attributes map from the HttpSession to validate that our method is storing the data that we expect.

Then I record the behavior of the mock during the controller.storeMyObjectInSession method execution and verify that both methods are being invoked (assuming that controller.storeMyObjectInsession gets and stores data once).

Finally, I use the sessionAttributes map that captured the attributes GameController usually stores in the httpSession to verify that it works as expected.