Tuesday, April 26, 2011

More servlet testing with Mockito and JUnit

Hello everyone,

I had some time to implement some more functionality for The Project today, so I thought I'd share more with you about testing our servlets.

Last time we were testing a server's JSON response to make sure it called the right validators and handled bad inputs.

Today we're testing the response of a POST request (also via AJAX). Our target: A simple controller that handles some very basic security (sufficient for our purposes). We want to send a request to the server and set a session variable if the user is authenticated. We are using JUnit integrated into Eclipse.

So first, in our TestAdminController*:

import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;

 Naturally we'll have more than one test case, so we will put some of the common code into a setup() method that is run before each test case is executed:

private AdminController controller; 
private HttpServletRequest stubRequest;
private HttpServletResponse stubResponse; 
private HttpSession stubSession;  

@Before
public void setup()
{
    controller = new AdminController();     
    stubRequest = mock(HttpServletRequest.class);
    stubResponse = mock(HttpServletResponse.class); 
    stubSession = mock(HttpSession.class);  
}


As always we've stubbed the request and response. This time we're also stubbing a session since we'll be setting a session attribute.

Now we set up one of our test cases: simply testing that, given a valid user, the session variable is set by the server. To do this we first hook up our HttpServletRequest so that when the server attempts to retrieve the current session, it returns a stub instead. We also setup a stub user manager (which handles authentication) so that we don't have to worry about usernames and passwords and all those things:

when(stubRequest.getSession()).thenReturn(stubSession);
when(stubRequest.getParameter("password")).thenReturn(UserManager.SUPER_SECRET_ADMIN_PASSWORD); 
UserManager stubUserManager  = new UserManager(); 
when(stubUserManager.userIsAuthenticated(Mockito.anyString(), Mockito.anyString())).thenReturn(true)

We use Mockito.anyString() because we don't care what credentials have been retrieved, but we always declare the user as valid. This decouples the test from the UserManager class.

Finally, we are ready to initialize the controller:
AdminController controller = new AdminController();
controller.setUserManager(stubUserManager);
controller.doPost(stubRequest, stubResponse);         

To ensure that the server set the session variable, we use verify() to determine that the HttpSession.setAttribute() method was called:

verify(stubSession).setAttribute("authenticated", true);

Now we can run the test and if everything is working, it should pass. In this way, we have ensured that at least some parts of the controller are working so any problems will be on the client.

Well, that's all for now!

*I put the imports here because I hate it when I find a solution to something, but the author doesn't list the imports and the library isn't easily searchable!

No comments:

Post a Comment