Thursday, February 25, 2010

Mockito Mocks Rock For Service Requests and Responses

My mocking framework of choice when Unit Testing with JUnit is Mockito. You will hear me preach about readability and, used in conjunction with hamcrest matchers, Mockito achieves that.

Recently I was tasked with testing server side code that could handle requests and sent responses to a socket server. This is not an easy job as most socket servers have their own API which is untouchable. One option is to create an accessor class for the class you are testing and overwriting the method calls. Really not that friendly, but I will post about that option in the future. The second option is using Mockito and developing code that allows Dependency Injection on the socket servers main extension class. If someone requires more details on how to do that, please ask and I will post on that.

Using Mockito you can verify a response was sent when a request was handled by the class with specific parameters. Take this code as an example (obviously I left this as ambigous as possible and the code is unrealistic):

public void handleMoveRequest(String[] command, User user)
{
if (command[0] == "Forward")
{
user.moveForward();
// this depends on the socket server API for the exact call
extension.sendTheResponse(command, user, user.getCurrentLocation());
}
else
{
user.moveBackwards();
extension.sendTheResponse(command, user, user.getCurrentLocation());
}
}


The only way to test the result of the communication with the socket server (from a Unit Testing standpoint) is to Mock the socket server's extension and verify the parameters in the response. Here is how Mockito allows us to do that:




// Assume that the mock objects were previously instantiated
@Test
public void canMoveForward()
{
String[] command = new String[] {"Forward"};
when(mockUser.getCurrentLocation()).thenReturn("1, 1");
handler.handleMoveRequest(command, mockUser);
verify(mockUser).moveForward();
verify(mockExtension).sendTheResponse(command, mockUser, mockUser.getCurrentLocation());
}


There are many who say there should be one test (assertion) to each test case. Really this is one behaviour that requires 2 checks. If we made separate tests, we would really be duplicating code.

I leave you with this... what if we wanted to test with a real user? The method 'getCurrentLocation' would probably return a different result after 'moveForward' was called. We can also use Mockito to help with that. I will show how in the next post.

No comments:

Post a Comment