Thursday 19 April 2012

How to unit test with @ResponseBody return Json in Spring MVC controller

  1. model
  2. public class Dealer {
        private String id;
        private String name;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
  3. Controller
  4. import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.annotation.Resource;
    import java.util.List;
    
    @Controller
    @RequestMapping("/dealer")
    public class DealerController {
        @Resource(name = "dealerService")
        private DealerService dealerService;
    
        @RequestMapping("json/all")
        public @ResponseBody List<Dealer> getAllDealers() {
            return dealerService.getAllDealers();
        }
    }
    
  5. applicationContext.xml
  6. 
        
            
                <entry key="xml" value="application/xml" />
                <entry key="json" value="application/json" />
            
        
        
            
               <bean class="org.springframework.web.servlet.view.xml.MarshallingView" p:marshaller-ref="unmarshaller" />
               <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" p:objectMapper-ref="jacksonJsonObjectMapper" />
            
        
    
    
    
        <oxm:class-to-be-bound name="mypackge.Dealer"/>
    
    
  7. Unit test
  8. import com.google.common.collect.Lists;
    import org.apache.http.HttpHeaders;
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.http.MediaType;
    import org.springframework.http.converter.HttpMessageConverter;
    import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
    import org.springframework.mock.web.MockHttpServletRequest;
    import org.springframework.mock.web.MockHttpServletResponse;
    import org.springframework.test.util.ReflectionTestUtils;
    import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
    
    import java.util.List;
    
    import static org.junit.Assert.assertEquals;
    import static org.mockito.Mockito.mock;
    import static org.mockito.Mockito.when;
    
    public class TestDealerController {
        private DealerController dealerController;
    
        @Before
        public void before() throws Exception {
            DealerService dealerService = mock(DealerService.class);
            when(dealerService.getAllDealers()).thenReturn(mockDealers());
            
            dealerController = new DealerController();
            ReflectionTestUtils.setField(dealerController, "dealerService", dealerService);
        }
    
        @Test
        public void testGetAllDealers() throws Exception {
            MockHttpServletRequest mockRequest = new MockHttpServletRequest();
            mockRequest.setContentType(MediaType.APPLICATION_JSON.toString());
            mockRequest.addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON.toString());
            mockRequest.setMethod("GET");
            mockRequest.setRequestURI("/dealer/json/all");
    
            AnnotationMethodHandlerAdapter handlerAdapter = new AnnotationMethodHandlerAdapter();
            HttpMessageConverter[] messageConverters = {new MappingJacksonHttpMessageConverter()};
            handlerAdapter.setMessageConverters(messageConverters);
    
            MockHttpServletResponse mockResponse = new MockHttpServletResponse();
            handlerAdapter.handle(mockRequest, mockResponse, dealerController);
    
            String expected="[{\"id\":\"01\",\"name\":\"dealer-01\"}, {\"id\":\"02\",\"name\":\"dealer-02\"}]";
            assertEquals(expected, mockResponse.getContentAsString());
        }
    
        private List<Dealer> mockDealers() {
            Dealer dealer01 = new Dealer();
            dealer01.setId("01");
            dealer01.setName("dealer-01");
    
            Dealer dealer02 = new Dealer();
            dealer02.setId("02");
            dealer02.setName("dealer-02");
    
            return Lists.newArrayList(dealer01, dealer02);
        }
    
  9. reference
  10. Spring Framework TEST RESTful Web Service (Controller) Offline i.e. No Server, No Database

6 comments:

  1. excuse me sir. if i have 2 service . how can i make it in my testing....?
    example my code :
    @Before
    public void before() throws Exception {
    DealerService dealerService = mock(DealerService.class);
    DealerService2 dealerService2 = mock(DealerService2.class);
    when(dealerService.getAllDealers()).thenReturn(mockDealers());

    dealerController = new DealerController();
    ReflectionTestUtils.setField(dealerController, "dealerService", dealerService);
    ReflectionTestUtils.setField(dealerController, "dealerService2", dealerService2);
    }

    i get error...?

    thanks for advanced

    ReplyDelete
  2. i already fix it. i get error because my code like this :
    SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
    sdf.format(customer_info.getBirthdate()

    ReplyDelete
  3. spring 3.2 makes this obsolete - http://static.springsource.org/spring-framework/docs/current/spring-framework-reference/html/testing.html#spring-mvc-test-framework

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete