Monday, 17 November 2008

EasyMock and Spring Autowiring

Spring Framework provides an easy way to unit test components in isolation and EasyMock provides a quick way to create mock objects with very little effort. Combining them together, Spring can be used to create the mock objects so that beans that use auto wiring to inject dependencies can be tested without having to modify the classes or create complex context configuration files.

Creating mock objects using spring is simple, here is a sample beans.xml:
<bean class="org.easymock.EasyMock" factory-method="createNiceMock" primary="true" id="someServiceMock">
   <constructor-arg value="com.example.service.SomeService" />
This creates a mock object from the given interface. The primary is used to indicate that it should be used for autowiring which is useful when component scanning is used together with @Component tags. When you want to refer to the actual implementation you would use @Qualifier("someService").

If interfaces aren't used then the following beans.xml is used.
<bean class="org.easymock.classextension.EasyMock" factory-method="createNiceMock" primary="true" id="someDAO" >
   <constructor-arg value="com.example.dao.SomeDAO" />
   <property name="sessionFactory">
      <null />
Performing the test is relatively simple and with autowiring configuration is minimal. Below I have used the classextension static imports as it can be used for both types of mocks. However the standard expect/replay/etc cannot be used with classextension created mocks.
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import org.junit.Before;
import org.junit.Test;
import org.springframework.ui.ModelMap;

@ContextConfiguration(locations = { "classpath:/controller-beans.xml" })
public class TestSampleController
   private SampleController controller;
   /** mock object */
   private SampleService service;

   * Called before each test.
   public void setUp() throws Exception

   public void testPage() throws Exception
      List data = new LinkedList();


      ModelMap map = new ModelMap();
      String result =;

      assertThat("result", result, equalTo("expected");
      assertThat((Map<String,Object>) map, Matchers.hasKey("someobj"));
      assertThat("someobj", map.get("someobj"), notNullValue());
Finally there are cases where you need the mock object ready to give a response during load up, such as in an InitializingBean. In those cases the following util class can be adapted:
public class MockUtil
   public static <T> T createNiceMock(Class<T> toMock, boolean replay)
      IMocksControl control = EasyMock.createNiceControl();
      T mock = control.createMock(toMock);
      if (replay)
      return mock;
<bean id="dataServiceMock" class="com.example.test.MockUtil"  factory-method="createNiceMock" primary="true">
   <constructor-arg value="com.example.service.DataService" />
   <constructor-arg value="true"/>

No comments:

Post a Comment