Web API 테스트 코드 작성

Minkyeong Kim·2021년 12월 6일
0

[boostcourse] Web-Backend

목록 보기
53/55

기존 방식의 문제점

Web API를 작성하고 테스트를 수행하기 위해서 스프링 부트 애플리케이션을 실행하고 Restlet이나 Swagger등을 이용해 개발자가 직접 테스트를 수행
-> Web API를 실행하는 시간보다 웹 어플리케이션을 실행하고 종료하는 시간이 더 오래걸리는 상황 발생

  • 해결 방안
    • JUnit 사용하기
    • MockMVC 사용하기

MockMVC 란?

  • Web API를 테스트하려면 WAS를 실행해야만 되는 문제 발생
  • MockMVC는 WAS와 같은 역할을 수행
  • 웹 어플리케이션을 실행하기 위한 최소한의 기능만을 가지고 있어 WAS에 비해 빠름
  • 아래와 같은 테스트 가능

MockMVC로 GuestbookApiController 테스트하기


GuestbookApiController에서는 GuestbookService라는 서비스 객체를 가져와 사용하지만, 테스트할 경우 Mock 객체를 생성해 사용하도록 함

1) GuestbookApiControllerTest 클래스 생성

package kr.or.connect.guestbook.controller;

import kr.or.connect.guestbook.config.ApplicationConfig;
import kr.or.connect.guestbook.config.WebMvcContextConfiguration;
import kr.or.connect.guestbook.dto.Guestbook;
import kr.or.connect.guestbook.service.GuestbookService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = {WebMvcContextConfiguration.class, ApplicationConfig.class })
public class GuestbookApiControllerTest {
    // Mockito 프레임워크에 위해 생성된 Mock 객체를 사용할 수 있음
	@InjectMocks
    public GuestbookApiController guestbookApiController;
    
    //GuestbookApiControllerTest에서 사용되는 객체의 Mock 객체 생성
    @Mock
    GuestbookService guestbookService;

    //guestbookApiController를 테스트 하기 위한 MockMvc객체를 생성
    private MockMvc mockMvc;
    
    // 테스트 메소드 실행 전 @Before 어노테이션 붙은 메소드 실행
    @Before
    public void createController() {
    	// @Mock이 붙은 객체 초기화
        MockitoAnnotations.initMocks(this);
        // MockMVC타입의 변수 mockMvc를 초기화
        mockMvc = MockMvcBuilders.standaloneSetup(guestbookApiController).build();
    }
        
    @Test //테스트 메소드
    public void getGuestbooks() throws Exception {
        Guestbook guestbook1 = new Guestbook();
        guestbook1.setId(1L);
        guestbook1.setRegdate(new Date());
        guestbook1.setContent("hello");
        guestbook1.setName("kim");

        List<Guestbook> list = Arrays.asList(guestbook1);
        //when(목객체.목객체메소드호출()).threnReturn(목객체 메소드가 리턴 할 값)
      //guestbookService.getGuestbooks(0) 이 호출되면 위에서 선언된 list객체가 리턴 되도록 함
        when(guestbookService.getGuestbooks(0)).thenReturn(list);
        
        // MockMvcRequestBuilders를 이용해 MockMvc에 호출할 URL생성
        //application/json형식으로 /guestbooks를 GET방식으로 호출한다는 의미
        RequestBuilder reqBuilder = MockMvcRequestBuilders.get("/guestbooks").contentType(MediaType.APPLICATION_JSON);
        
        //mockMvc.perform(reqBuilder) 는 reqBuilder에 해당하는 URL에 대한 요청을 보냈다는 것을 의미
        // 상태코드값이 200이 나오면 처리 내용을 출력
        mockMvc.perform(reqBuilder).andExpect(status().isOk()).andDo(print());
        
        //Json 결과에 “name”:”kim”이 있을 경우에만 성공
        //mockMvc.perform(reqBuilder).andExpect(jsonPath("$.list[0].name").value("kim"));
        
        //Mock 객체의 getGuestbooks(0)메소드가 호출됐다면 검증 성공
        verify(guestbookService).getGuestbooks(0);
    }

    @Test
    public void deleteGuestbook() throws Exception {
        Long id = 1L;

        when(guestbookService.deleteGuestbook(id, "127.0.0.1")).thenReturn(1);
        
        // “/guestbooks/” + id 경로를 DELETE방식으로 호출하기 위한 경로 정보를 저장
        RequestBuilder reqBuilder = MockMvcRequestBuilders.delete("/guestbooks/" + id).contentType(MediaType.APPLICATION_JSON);
        //reqBuilder에 해당하는 URL호출 후 상태코드가 200일때 실행 결과 출력
        mockMvc.perform(reqBuilder).andExpect(status().isOk()).andDo(print());
        
        //guestbookService 목객체의 deleteGuestbook(id, “127.0.0.1”)메소드가 Web API가 동작하면서 호출되었다면 성공
        verify(guestbookService).deleteGuestbook(id, "127.0.0.1");
    }
}
  • Run As .. > Junit Test로 실행

2) Get 테스트 결과

3) Delete 테스트 결과

0개의 댓글