Tuesday, June 21, 2011

Test driven development for Web application in Spring.

I have been curious to do some unit-testing in spring and looking at spring documentation, I learnt it supports test driven development using Mock Objects. At my company, we are still on spring 2. After doing some research, following are the things I learnt.


With respect to MVC framework, org.springframework.mock.web package contains classes which can be used for testing. Key classes in this package MockHttpServletRequest and MockHttpServletResponse which simulate request and response objects.


My main motivations for doing so:
1) Most importantly development cycle is drastically improved. Our web code, takes a hell lot of time to start as it loads lot of data which at times is not needed to test code in isolation.
2) Our web code also depends on other projects over the network which might be down.
3) Lastly I had some free cycles and thought this would be a good exercise for me to refer if I ever forget how to write a test case! :)

Considering my motivations, I wrote a test case for a spring controller using org.springframework.mock.web package

Solution: I wrote the controller named MyController and used it inside my test (ControllerTest) class, after instantiating it from ApplicationContext. Note MyController is instantiated in a method setUpBeforeClass method which has a annotation of @BeforeClass, which is annotation supported by Junit 4. All it denotes is execute before the main tests. As in the below code snippet, I am using mock requests and response to simulate HttpServletRequest and HttpServletResponse and testing model returned is not null.

Following is the snippet:

// packages and imports statements.

public class ControllerTest {
  private static final Log logger = LogFactory.getLog(ControllerTest.class);
  private static MyController controller; // controller in test.

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
    ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {
      "classpath:applicationContext.xml"
    });
    controller = (MyController) context.getBean("MyController");
  }

  @Test
  public void controllerTestWithData() throws Exception {
    MockHttpServletRequest request = new MockHttpServletRequest();
    request.addParameter("url", "/adamcontent/cancer");
    request.setMethod("GET");
    MockHttpServletResponse response = new MockHttpServletResponse();
    ModelAndView mav = controller.handleRequest(request, response);
    Map data = mav.getModel();
    logger.debug("data = " + data.toString());
    Assert.assertNotNull(data);
  }
}

If our code base used spring 2.5 and above, I could have written the same unit test a little differently. Following is the difference:


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class ControllerTest {
  private static final Log logger = LogFactory.getLog(ControllerTest.class);

  @Autowired private static MyController controller; // controller in test.

  @Test
  public void controllerTestWithData() throws Exception {
    MockHttpServletRequest request = new MockHttpServletRequest();
    request.addParameter("url", "/adamcontent/cancer");
    request.setMethod("GET");
    MockHttpServletResponse response = new MockHttpServletResponse();
    ModelAndView mav = controller.handleRequest(request, response);
    Map data = mav.getModel();
    logger.debug("data = " + data.toString());
    Assert.assertNotNull(data);
  }
}


As seen in the snippet using spring 2.5, code is reduced through annotations. I have specifically used @Autowired annotation which can be used to substitute a setter method. More on annotations can be found at link.

1 comment:


  1. I was very interested in the article , it’s quite inspiring I should admit. I like visiting your site since I always come across interesting articles like this one. Keep sharing! Regards. Read more about
    Offshore software testing services
    software testing services company
    software testing services
    Software Qa Services
    quality assurance service providers
    Performance testing services
    Security testing services

    ReplyDelete