복붙노트

[SPRING] Spring Framework 테스트 RESTful 웹 서비스 (컨트롤러) 오프라인 (즉, 서버 없음, 데이터베이스 없음)

SPRING

Spring Framework 테스트 RESTful 웹 서비스 (컨트롤러) 오프라인 (즉, 서버 없음, 데이터베이스 없음)

JSON을 소비하고 생성하는 매우 간단한 RESTful 컨트롤러가 있습니다. 이 컨트롤러를 오프라인으로 테스트 (즉, 실행중인 서버가없고 데이터베이스가 실행 중이 아님)해야합니다. 그리고 나는 해결책을 찾을 수 없다는 이유로 열망하고 있습니다. 내 초기 테스트 케이스에는 다음이 포함됩니다.

다음과 같은 URI가 있습니다.

참고 : 이것은 일반적인 MVC 응용 프로그램이 아닙니다. 나는 전망이 없다. JSON 형식을 사용하고 JSON 형식의 데이터를 사용하는 순수 REST 컨트롤러가 있습니다.

누군가가 올바른 방향으로 나를 인도 할 수 있다면 정말 감사 할 것입니다.

내 코드가 어떻게 보이는지 분명히하기 위해서 :

@Controller
@RequestMapping("/pcusers")
public class PcUserController {
    protected static Logger logger = Logger.getLogger(PcUserController.class);

    @Resource(name = "pcUserService")
    private PcUserService pcUserService;

    @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json")
    @ResponseBody
    public List<PcUser> readAll() {
        logger.debug("Delegating to service to return all PcUsers");
        return pcUserService.readAll();
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET, consumes = "application/json", produces = "application/json")
    @ResponseBody
    public PcUser read(@PathVariable String id) {
        logger.debug("Delegating to service to return PcUser " + id);
        return pcUserService.read(id);
    }

    @RequestMapping(value = "/create/{pcUser}", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
    @ResponseBody
    public boolean create(@PathVariable PcUser pcUser) {
        logger.debug("Delegating to service to create new PcUser");
        return pcUserService.create(pcUser);
    }

    @RequestMapping(value = "/update/{pcUser}", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
    @ResponseBody
    public boolean update(@PathVariable PcUser pcUser) {
        logger.debug("Delegating to service to update existing PcUser");
        return pcUserService.update(pcUser);
    }

    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
    @ResponseBody
    public boolean delete(@PathVariable String id) {
        logger.debug("Delegating to service to delete existing PcUser");
        return pcUserService.delete(id);
    }
}

업데이트 (2012/2/5) : 몇 가지 연구 끝에 spring-test-mvc라는 스프링 프레임 워크를 발견했습니다. 그것은 매우 유망 해 보입니다. 그리고 저는 이것에 대해 좋은 출발을 할 수있었습니다. 하지만 지금은 새로운 문제가 있습니다. "/ pcusers / {id}"에 GET 요청을 제출하면 해당 매핑을 처리하는 read 메소드로 컨트롤이 전달됩니다. 그 방법 안에는 내가 읽는 pcUserService가 있습니다. 이제 문제는이 테스트를 실행할 때 실제 컨트롤러 내부의 pcUserService 인스턴스가 NULL 인 것입니다. 따라서 NULL 객체에서 read를 호출 할 수 없으므로 충돌이 발생합니다.

PcUserControllerTest 코드는 다음과 같습니다.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/applicationContextTest.xml")
public class PcUserControllerTest {

    @Autowired
    PcUserService pcUserService;

    @Autowired
    PcUserController pcUserController;

    PcUser pcUser;

    @Before
    public void setUp() throws Exception {
        pcUser = new PcUser("John", "Li", "Weasley", "john", "john", new DateTime());

        pcUserService.create(pcUser);
    }

    public void tearDown() throws Exception {
        pcUserService.delete(pcUser.getId());
    }

    @Test
    public void shouldGetPcUser() throws Exception {
        standaloneSetup(pcUserController)
                .build()
                .perform(get("/pcusers/" + pcUser.getId()).accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk());
    }
}

해결법

  1. ==============================

    1.몇 가지 아이디어를 제시해야합니다. SpringJUnit4ClassRunner와 @ContextConfiguration에 익숙하다고 가정합니다. 먼저 PcUserController와 조롱 된 PcUserService가 포함 된 테스트 응용 프로그램 컨텍스트를 만듭니다. 아래 예제 PcUserControllerTest 클래스에서 Jackson은 JSON 메시지를 변환하는 데 사용되고 Mockito는 조롱을 위해 사용됩니다.

    몇 가지 아이디어를 제시해야합니다. SpringJUnit4ClassRunner와 @ContextConfiguration에 익숙하다고 가정합니다. 먼저 PcUserController와 조롱 된 PcUserService가 포함 된 테스트 응용 프로그램 컨텍스트를 만듭니다. 아래 예제 PcUserControllerTest 클래스에서 Jackson은 JSON 메시지를 변환하는 데 사용되고 Mockito는 조롱을 위해 사용됩니다.

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(/* Insert test application context here */)
    public class PcUserControllerTest {
    
        MockHttpServletRequest requestMock;
        MockHttpServletResponse responseMock;
        AnnotationMethodHandlerAdapter handlerAdapter;
        ObjectMapper mapper;
        PcUser pcUser;
    
        @Autowired
        PcUserController pcUserController;
    
        @Autowired
        PcUserService pcUserServiceMock;
    
        @Before
        public void setUp() {
            requestMock = new MockHttpServletRequest();
            requestMock.setContentType(MediaType.APPLICATION_JSON_VALUE);
            requestMock.addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
    
            responseMock = new MockHttpServletResponse();
    
            handlerAdapter = new AnnotationMethodHandlerAdapter();
            HttpMessageConverter[] messageConverters = {new MappingJacksonHttpMessageConverter()};
            handlerAdapter.setMessageConverters(messageConverters);
    
            mapper = new ObjectMapper();
            pcUser = new PcUser(...);
    
            reset(pcUserServiceMock);
        }
    }
    

    이제 테스트를 작성하는 데 필요한 모든 코드가 있습니다.

    @Test
    public void shouldGetUser() throws Exception {
        requestMock.setMethod("GET");
        requestMock.setRequestURI("/pcusers/1");
    
        when(pcUserServiceMock.read(1)).thenReturn(pcUser);
    
        handlerAdapter.handle(requestMock, responseMock, pcUserController);
    
        assertThat(responseMock.getStatus(), is(HttpStatus.SC_OK));
        PcUser actualPcUser = mapper.readValue(responseMock.getContentAsString(), PcUser.class);
        assertThat(actualPcUser, is(pcUser));
    }
    
    
    @Test
    public void shouldCreateUser() throws Exception {
        requestMock.setMethod("POST");
        requestMock.setRequestURI("/pcusers/create/1");
        String jsonPcUser = mapper.writeValueAsString(pcUser);
        requestMock.setContent(jsonPcUser.getBytes());
    
        handlerAdapter.handle(requestMock, responseMock, pcUserController);
    
        verify(pcUserServiceMock).create(pcUser);
    }
    
  2. from https://stackoverflow.com/questions/9138555/spring-framework-test-restful-web-service-controller-offline-i-e-no-server-n by cc-by-sa and MIT license