`
sillycat
  • 浏览: 2481821 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Spring3 and REST Integration(IV)Controller JUnit Test and Mock/Servlet

 
阅读更多
Spring3 and REST Integration(IV)Controller JUnit Test and Mock/Servlet

There are 4 different ways to JUnit our REST style JSON data Controller.
Servlet Mock
The first way is to use Servlet Mock. There are 2 base classes needed in our project
The Mock Web Application Loader class will be like these:
package com.sillycat.easyrestserver.core;

import javax.servlet.ServletException;

import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.SourceFilteringListener;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.FileSystemResourceLoader;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.context.MergedContextConfiguration;
import org.springframework.test.context.support.AbstractContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

public class MockWebApplicationContextLoader extends AbstractContextLoader {

     MockWebApplication configuration;

     static MockServletContext servletContext;

     static MockServletConfig servletConfig;

     static XmlWebApplicationContext webApplicationContext;

     public ApplicationContext loadContext(
               MergedContextConfiguration mergedConfig) throws Exception {
          servletConfig = new MockServletConfig(servletContext,
                    configuration.name());
          servletContext = new MockServletContext(configuration.webapp(),
                    new FileSystemResourceLoader());
          webApplicationContext = new XmlWebApplicationContext();
          webApplicationContext.getEnvironment().setActiveProfiles(
                    mergedConfig.getActiveProfiles());
          servletContext.setAttribute(
                    WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
                    webApplicationContext);
          webApplicationContext.setServletConfig(servletConfig);
          webApplicationContext.setConfigLocations(configuration.locations());

          prepareWebApplicationContext();

          return webApplicationContext;
     }

     public ApplicationContext loadContext(String... locations) throws Exception {
          servletConfig = new MockServletConfig(servletContext,
                    configuration.name());
          servletContext = new MockServletContext(configuration.webapp(),
                    new FileSystemResourceLoader());
          webApplicationContext = new XmlWebApplicationContext();
          servletContext.setAttribute(
                    WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
                    webApplicationContext);
          webApplicationContext.setServletConfig(servletConfig);
          webApplicationContext.setConfigLocations(locations);
          prepareWebApplicationContext();
          return webApplicationContext;
     }

     private void prepareWebApplicationContext() throws ServletException {
          @SuppressWarnings("serial")
          final DispatcherServlet dispatcherServlet = new DispatcherServlet() {
               protected WebApplicationContext createWebApplicationContext(
                         ApplicationContext parent) {
                    return webApplicationContext;
               }
          };
          webApplicationContext
                    .addBeanFactoryPostProcessor(new BeanFactoryPostProcessor() {
                         public void postProcessBeanFactory(
                                   ConfigurableListableBeanFactory beanFactory) {
                              beanFactory.registerResolvableDependency(
                                        DispatcherServlet.class, dispatcherServlet);
                         }
                    });
          webApplicationContext
                    .addApplicationListener(new SourceFilteringListener(
                              webApplicationContext,
                              new ApplicationListener<ContextRefreshedEvent>() {
                                   public void onApplicationEvent(
                                             ContextRefreshedEvent event) {
                                        dispatcherServlet.onApplicationEvent(event);
                                   }
                              }));
          webApplicationContext.refresh();
          webApplicationContext.registerShutdownHook();
          dispatcherServlet.setContextConfigLocation("");
          dispatcherServlet.init(servletConfig);
     }

     protected String[] generateDefaultLocations(Class<?> clazz) {
          extractConfiguration(clazz);
          return super.generateDefaultLocations(clazz);
     }

     protected String[] modifyLocations(Class<?> clazz, String... locations) {
          extractConfiguration(clazz);
          return super.modifyLocations(clazz, locations);
     }

     private void extractConfiguration(Class<?> clazz) {
          configuration = AnnotationUtils.findAnnotation(clazz,
                    MockWebApplication.class);
          if (configuration == null) {
               throw new IllegalArgumentException("Test class " + clazz.getName()
                         + " must be annotated @MockWebApplication.");
          }
     }

     protected String getResourceSuffix() {
          return "-context.xml";
     }
}


And we will use the mockwebapplication class to hold our annotation configuration:
package com.sillycat.easyrestserver.core;

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MockWebApplication {
     String webapp() default "src/main/webapp";

     String name();
   
     String[] locations() default "src/test/test-content.xml";
}


The test class will be like this:
package com.sillycat.easyrestserver.controller;

import java.io.IOException;

import javax.servlet.ServletException;

import org.codehaus.jackson.map.ObjectMapper;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerMapping;

import com.sillycat.easyrestserver.core.MockWebApplication;
import com.sillycat.easyrestserver.core.MockWebApplicationContextLoader;
import com.sillycat.easyrestserver.model.Company;
import com.sillycat.easyrestserver.model.Person;

/**
* mock the servlet and use servlet to test our controller
* servlet.service(mockRequest, mockResponse);
* can not mock the service or manager in controller
* @author karl
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = MockWebApplicationContextLoader.class)
@MockWebApplication(name = "easyrestserver", locations = "classpath:test-context.xml")
public class PersonControllerTest1 {

     @Autowired
     private DispatcherServlet servlet;

     ObjectMapper mapper;
     Person person;
     MockHttpServletRequest mockRequest;
     MockHttpServletResponse mockResponse;

     @Before
     public void setUp() throws ServletException, IOException {
          MockitoAnnotations.initMocks(this);
          mapper = new ObjectMapper();
          person = new Person();
          person.setCompany(new Company());
          person.setId(1);
          person.setPersonName("person1");
        
          mockRequest = new MockHttpServletRequest();
          mockRequest.setAttribute(HandlerMapping.INTROSPECT_TYPE_LEVEL_MAPPING,true);
        
          mockResponse = new MockHttpServletResponse();
     }
   

     @Test
     public void get() throws Exception {
          mockRequest.setMethod("GET");
          mockRequest.setRequestURI("/person/1");
          mockRequest.setContentType(MediaType.APPLICATION_JSON_VALUE);
          mockResponse = new MockHttpServletResponse();

          servlet.service(mockRequest, mockResponse);

          Person actualPerson = mapper.readValue(
                    mockResponse.getContentAsString(), Person.class);
          Assert.assertEquals(actualPerson.getId(), person.getId());
     }
   
     @Test
     public void add() throws Exception{
          mockRequest.setContentType(MediaType.APPLICATION_JSON_VALUE);
          mockRequest.setMethod("POST");
         mockRequest.setRequestURI("/person");
       
         String jsonPerson = mapper.writeValueAsString(person);
         mockRequest.setContent(jsonPerson.getBytes());

         servlet.service(mockRequest, mockResponse);
       
         Assert.assertEquals(mockResponse.getStatus(), 200);
          Person actualPerson = mapper.readValue(
                    mockResponse.getContentAsString(), Person.class);
          Assert.assertEquals(actualPerson.getId(), person.getId());
     }
}


The sample project named easyrestserver.

references:
spring 3 and rest
http://hi.baidu.com/luohuazju/blog/item/1fe358ea5da873c0d539c9b4.html
http://hi.baidu.com/luohuazju/blog/item/c380b67f9946421b28388ab7.html
http://hi.baidu.com/luohuazju/blog/item/3b68f609650a37dc3bc763c5.html

tcpdump on mac
http://support.apple.com/kb/HT3994
http://hi.baidu.com/luohuazju/blog/item/da079eb3de7109b2d9335aa5.html

mock test
http://www.iteye.com/topic/828513
http://stackoverflow.com/questions/9138555/spring-framework-test-restful-web-service-controller-offline-i-e-no-server-n
http://stackoverflow.com/questions/1401128/how-to-unit-test-a-spring-mvc-controller-using-pathvariable/2457902#2457902
http://ted-young.googlecode.com/svn/trunk/blog.spring-mvc-integration-testing/
https://github.com/springside/springside4/blob/master/examples/mini-service/src/test/java/org/springside/examples/miniservice/webservice/ws/AccountWebServiceTest.java
https://github.com/SpringSource/spring-test-mvc
http://elf8848.iteye.com/blog/875830
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics