David Chandler's Journal of Java Web and Mobile Development

  • David M. Chandler

    Web app developer since 1994 and Google Cloud Platform Instructor now residing in Colorado. Besides tech, I enjoy landscape photography and share my work at ColoradoPhoto.gallery.

  • Subscribe

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 224 other followers

  • Sleepless Nights…

    December 2009
    S M T W T F S
  • Blog Stats

    • 1,034,589 hits

Archive for December 14th, 2009

Unit testing with MockHttpSession and Guice

Posted by David Chandler on December 14, 2009

The more I learn about Guice, the more I like it. First, I discovered I could get access to the HttpSession inside my Guice-injected service classes (which are in turn called from my Guice-injected gwt-dispatch ActionHandlers) like this:

public class ROAUserServiceImpl implements ROAUserService
	Provider<HttpSession> httpSession;

	public LoginInfo login(String requestUri)

Then came the unhappy moment that I ran my unit tests, which call ActionHandlers, all of which call ROAUserService to verify that the user is logged in. In my unit test environment, Guice cannot inject an HttpSession because my tests are not currently running in a servlet container; thus, every test fails.

I could bring in HttpUnit / ServletRunner, but that is really overkill for what I’m trying to do at this point, which is just to simulate one session attribute being set to represent the logged in user.

I could also create a mock ROAUserService and inject that in my ActionHandlers instead of the real one. But I’d prefer to use the real service for testing, and sooner or later, I’ll need to stuff something else in session, anyway.

Enter Guice Providers.

In the example above, the HttpSession is being injected by way of a Guice Provider, which in the real app, comes for free when your Guice injector includes a ServletModule. Fortunately, we can easily tell Guice to provide a mock HttpSession by using the @Provides annotation in a plain old AbstractModule (no ServletModule required):

package com.turbomanage.gwt.server.guice;

import javax.servlet.http.HttpSession;

import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.roa.test.mock.MockHttpSession;

public class DispatchTestModule extends AbstractModule
	protected void configure()
		// application bindings here

	HttpSession getMockSession()
		return new MockHttpSession();

I could probably snag a mock session from some other framework, but all I need to do is get and set attributes, hence:

package com.roa.test.mock;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext;

public class MockHttpSession implements HttpSession
	private Map<String, Object> attributes = new HashMap<String, Object>();

	public Object getAttribute(String name)
		return attributes.get(name);

	public void setAttribute(String name, Object value)
		attributes.put(name, value);

	// All other methods auto-generated

Now my TestCase setUp() method can simulate user login, logout, etc. by calling the real ROAUserService, which Guice provides with our mock HttpSession.

		User u = addTestUser();
		Injector inj = Guice.createInjector(..., new DispatchTestModule());
		ROAUserService userService = inj.getInstance(ROAUserService.class);

Guice Providers can also accept user-defined annotations to allow you to select among multiple implementations of a provided class. That might be another handy testing tool…

Posted in GIN / Guice | 3 Comments »

%d bloggers like this: