Showing posts with label Unit testing. Show all posts
Showing posts with label Unit testing. Show all posts

Sunday, August 28, 2011

Spring: Unit Test, Reload Context After Each Test Or Test Class

Recently I came across a situation while doing some unit test using spring SpringJUnit4ClassRunner where after each test, the spring application context is no longer good for it to be reused in the next test. After some digging, I found out that there is this DirtiesContext annotation which one can use in the unit test to force spring to reload context.

It has two options:

(1) One is reload context after each test.
(2) Second is to reload context after all the tests of a class.

This is very useful and it also means that when running unit test using spring, by default the application context is loaded once and used to run all the tests.

Promote your blog

Monday, September 6, 2010

Spring: Using Mock Objects For Unit Testing MVC Controllers

Spring has a nice framework to unit test controller for web/rest applications and it integrates nicely with Junit.Assuming that you wrote a CustomerController for handling REST requests to create a customer. A basic CustomerController looks like this:

@Controller
@RequestMapping("/customers")
public class CustomerController {


@RequestMapping (method = RequestMethod.POST)
public void createCustomer(HttpServletRequest request,
                  HttpServletResponse response) {
//your code here
}
}


Now to test this controller using Spring Mock objects, the basic steps are as follows in your unit test:

Step1: Declare that you want to run test using JUnit. For example to run test using JUnit4 you need to use @RunWith annotation as follows:

@RunWith(SpringJUnit4ClassRunner.class)
public class CustomerControllerTest extends TestCase {

@Test
public void testCreateCustomer() throws Exception {
}

}


Step2: Specify the spring bean configuration using @ContextConfiguration so that Controller works from unit test.



@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/customer/rest-config.xml")
public class CustomerControllerTest extends TestCase {

@Test
public void testCreateCustomer() throws Exception {
}

}


Step3: Setup DispatcherServlet. DispatchServlet will be used to send mock request to the controller. Setting up DispatchServlet requires implementing ApplicationContextAware.


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/customer/rest-config.xml")
public class CustomerControllerTest extends TestCase implements ApplicationContextAware {

private Servlet servlet;
 private ApplicationContext applicationContext;

@SuppressWarnings("serial")
@Before
private void init() {
servlet = new DispatcherServlet() {

@Override
protected WebApplicationContext createWebApplicationContext(
WebApplicationContext parent) throws BeansException {
GenericWebApplicationContext genericContext = new GenericWebApplicationContext();
genericContext.setParent(applicationContext);
genericContext.refresh();
return genericContext;
}

};
}

@Test
public void testCreateCustomer() throws Exception {
}

public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
this.applicationContext = arg0;
}

}


Step4: Finally use MockHttpServletRequest to build the request, send it and process the response.




@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/customer/rest-config.xml")
public class CustomerControllerTest extends TestCase implements ApplicationContextAware {

private Servlet servlet;
private ApplicationContext applicationContext;

@SuppressWarnings("serial")
@Before
private void init() {
servlet = new DispatcherServlet() {

@Override
protected WebApplicationContext createWebApplicationContext(
WebApplicationContext parent) throws BeansException {
GenericWebApplicationContext genericContext = new GenericWebApplicationContext();
genericContext.setParent(applicationContext);
genericContext.refresh();
return genericContext;
}

};
}

@Test
public void testCreateCustomer() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
// set uri, request parameter, request body, omitted here
MockHttpServletResponse response = new MockHttpServletResponse();

// send the request
MockServletConfig servletConfig = new MockServletConfig();
servlet.init(servletConfig);
servlet.service(request, response);

// validate response
String responseContent = response.getContentAsString();
int responseCode = response.getStatus();

}

public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
this.applicationContext = arg0;
}

}
Promote your blog