tags:

views:

196

answers:

2

Hi All,

Need help is deciding what approach needs to be taken to test below piece of code

I have one method called

private messageDAOInf messageDAO;

public Response verifyUser(Request request) {
    Response response = null;

    if (someCondition) {
        /* -----------Some processing here---------- */
    } else {
        response = constructResponse(errorCode, errorDesc);     
    }

    // Do more processing with messages from response
    response = messageDAOInf
        .convertMessagesAsAppropriate(response);

    return response;
}

My EasyMock code is here

/** The message dao inf. */
private MessageDAOInf messageDAOInf;

private VerifyUserService verifyUserServiceI;

@Before

public void setUp() throws Exception {
    messageDAOInf = EasyMock.createMock(MessageDAOInf.class);
    verifyUserService = new VerifyUserService();
    verifyUserService.setMessageDAOInf(messageDAOInf);
}

@Test

public void testErrorResponse() {
    Request request = loadRequest();

    Response response = constructErrorResponse();

    EasyMock.expect(messageDAOInf.convertMessagesAsAppropriate(
        response)).andReturn(response);

    EasyMock.replay(messageDAOInf);

    Response response2 = verifyUserService.verifyUser(request);

    assertFailedResponse(response2);
}

The issue is from line

response = constructResponse(errorCode, errorDesc);     

it constructs error response in verifyUser method and passes it to messageDAOInf.convertMessagesAsAppropriate()

But with easy mock it passes some other instance (mocked one) and hence failes with error

java.lang.AssertionError: 
  Unexpected method call convertMessagesAsAppropriate(***Response@1bb35b***):
    convertMessagesAsAppropriate(***Response@1b5d2b2***): expected: 1, actual: 0
    at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:29)
    at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:56)

Let me know what approach I should take. Thank you.

A: 

I have found out way of doing it. You need to implement interface org.easymock.IArgumentMatcher

public class ObjectEquals implements IArgumentMatcher {


/** The expected. */
private Object expected;

/**
 * Instantiates a new criterion equals.
 * 
 * @param expected
 *            the expected
 */
public ObjectEquals(final Object expected) {
    this.expected = expected;
}

/* (non-Javadoc)
 * @see org.easymock.IArgumentMatcher#matches(java.lang.Object)
 */
public boolean matches(final Object actual) {
    return expected.getClass().equals(actual.getClass());
}

/* (non-Javadoc)
 * @see org.easymock.IArgumentMatcher#appendTo(java.lang.StringBuffer)
 */
public void appendTo(final StringBuffer buffer) {
    buffer.append("buffer(");
}

}

and in your test class add method

/*
     * Eq criterion.
     * 
     * @param criterion the criterion
     * 
     * @return the criterion
     */
    public static <T> T eqCriterion(final Class<T> className, Object object) {
        EasyMock.reportMatcher(new ObjectEquals(object));
        return null;
    }

Now while passing to easymock use method eqCriterion at line

EasyMock.expect(messageDAOInf.convertMessagesAsAppropriate(         
        response)).andReturn(response);         

In short replace above line with

EasyMock.expect(messageDAOInf.convertMessagesAsAppropriate(         
        eqCriterion(Response.class, response))).andReturn(response);         

This way it will use this mocked response instance instead of one generated by actual code.

Geeta Bapat
A: 

Your initial code expects that convertMessagesAsAppropriate will be called with the exact instance of Response that you created in the test: obviously it will not do that.

The correction you've made is essentially the same as using the built-in EasyMock.anyObject() method which will allow any Response instance. If that's all you want to check in your unit test, that's fine. Alternatively you can add extra logic into your ArgumentMatcher to prove that the Response that is passed as an argument really is an ErrorResponse, or Capture the response and examine it in your test. This all depends on your level of testing :-)

DoctorRuss