anyString() v/s anyString() in Mocking frameworks

So I was trying out mocking frameworks for the first time a few days ago, and there’s an interesting observation: even though EasyMock, PowerMock, and Mockito and said to be brothers-in-arms, there are a few nuances to take care of. One of them is the following.

There are convenience methods (called matchers) provided by both Mockito and EasyMock to define a message signature that can accept any value of a given parameter type. It is claimed, that these any implementations (e.g. anyObject, anyString, etc.) are interchangeable, but that does not seem to be the case.

Consider a very simple scenario, where one would want to mock a login() implementation. That is to say, success (true in this case) must be returned, regardless of the parameters passed.

class N {
    
    public boolean login(String username, String password) {
        
        return doLogin(username, password);
    
    }

    private boolean doLogin(String u, String p){
        
        //validate login
        //...
        //...
        
        return true;
    }
}

Now that the method is defined, let’s take a look at the test case where we would mock is call.

@Test
public void testMockLogin() throws Exception {
  
  // mocking only specific methods
  N n = createPartialMock(N.class, "doLogin", String.class, String.class);
  boolean expected = true;

  expectPrivate(n, "doLogin", anyString(), anyString()).andReturn(expected);
  replay(n);

  boolean actual = n.login("foo", "bar");

  verify(n);

  assertEquals("Expected and actual did not match", expected, actual);

}

Easy, peasy! Except for line no. 7, where anyString() is used via the import org.mockito.Matchers.anyString, causing the following exception:

java.lang.AssertionError:
Unexpected method call N.doLogin("foo", "bar"):
N.doLogin("", ""): expected: 1, actual: 0
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:44)
at org.powermock.api.easymock.internal.invocationcontrol.EasyMockMethodInvocationControl.invoke(EasyMockMethodInvocationControl.java:91)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:124)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:185)
at com.pugmarx.mock.N.doLogin(N.java)
...

The same test case passes when the anyString() implementation of Mockito is replaced by the implementation provided by EasyMock (via org.easymock.EasyMock.anyString).
If we dig a bit, we realize that one of the reasons could be that EasyMock.anyString returns null, as against the empty string returned by mockit.Matchers.anyString.

[Thank you for troig from the wonderful StackOverflow community for helping me on this query.]

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.