Skip to content

Latest commit

 

History

History
139 lines (110 loc) · 6.36 KB

File metadata and controls

139 lines (110 loc) · 6.36 KB

MockMvc

MockMvc?

  • 웹 어플리케이션을 애플리케이션 서버에 배포하지 않고 테스트용 MVC 환경을 만들어 요청 및 전송, 응답기능을 제공해주는 유틸리티 클래스. Mock(모의) 처리
  • 컨트롤러 테스트를 하고싶을 때 실제 서버에 구현한 애플리케이션을 올리지 않고 (서블릿 컨테이너를 사용하지 않고) 테스트용으로 시뮬레이션하여 MVC가 되도록 도와주는 클래스
  • MockMvc를 사용하면 컨트롤러를 실행해 보는 것 뿐만 아니라, 컨트롤러에서 반환되는 모델 객체의 내용이나 뷰의 이름 등을 검증할 수 있음
  • 과정은 다음과 같음
    • MockMvc를 생성한다
    • MockMvc에게 요청에 대한 정보를 입력한
    • 요청에 대한 응답값을 Expect를 이용하여 테스트
    • Expect가 모두 통과하면 테스트 통과
    • Expect가 1개라도 실패하면 테스트 실패
class ControllerTest{
	
    @Autowired
    private MockMvc mockMvc; // mockMvc 생성
    
    @Test
    public void testController() throws Exception{
    	
        String jjson = "{\"name\": \"Test Name\"}";
        
        //mockMvc에게 컨트롤러에 대한 정보를 입력하자.
        
        mockMvc.perform(get("test?query=food") //해당 url로 요청을 한다.
            .contentType(MediaType.APPLICATION_JSON) // Json 타입으로 지정
            .content(jjson) // jjson으로 내용 등록
            .andExpect(status().isOk()) // 응답 status를 ok로 테스트
            .andDo(print()); // 응답값 print
        )
        }
}

MockMvc 제공 메소드

1. perform()

  • MockMvc가 제공하는 메서드로 브라우저에서 서버에 URL 요청을 하듯 컨트롤러를 실행시킬 수 있음
  • perform() 메소드는 RequestBuilder 객체를 인자로 받고, 이는 MockMvcRequestBuilders의 정적 메소드를 이용해서 생성

2. MockMvcRequestBuilders

  • MvckMvcRequestBuilders의 메소드들은 GET, POST, PUT, DELETE 요청 방식과 매핑되는 get(), post(), put(), delete() 메소드를 제공
  • 이 메소드들은 MockHttpServletRequestBuilder 객체를 리턴하고, 이를 통해 HTTP 요청 관련 정보(파라미터, 헤더, 쿠키 등)를 설정할 수 있음
  • 요청 설정 메소드는 아래와 같음
    • param/params : 쿼리 스트링 설정
    • cookie : 쿠키 설정
    • requestAttr : 요청 스코프 객체 설정
    • sessionAttr : 세션 스코프 객체 설정
    • content : 요청 본문 설정(body)
    • contentType : 본문 타입 설정
    • header/headers : 요청 헤더 설정

3. andExpect()

  • perform() 메소드를 이용하여 요청을 전송하면, 그 결과로 ResultActions 객체를 리턴하는데 이 객체는 응답 결과를 검증할 수 있는 andExpect() 메소드를 제공
  • andExpect()가 요구하는 ResultMatcher는 MockMvcResultMatchers에 정의된 정적 메소드를 통해 생성할 수 있음
  • MockMvcResultMatcher 객체는 컨트롤러가 어떤 결과를 전송했는지, 서버의 응답 결과를 검증

MockMvcResultMatcher 객체가 제공하는 메소드

1. 응답 상태 코드 검증

  • isOK() : 응답 상태코드가 정상적인 처리(200)인지 확인
  • isNotFound() : 응답 상태코드가 404 Fot Found인지 확인
  • isMethodNotAllowed() : 응답 상태코드가 메소드 불일치(405)인지 확인
  • isInternalServerError() : 응답 상태코드가 예외발생(500)인지 확인
  • is(int status) : 특정 응답 상태코드가 설정되어있는지 확인

2. 뷰/리다이렉트 검증

  • 컨트롤러가 리턴하는 뷰를 검증할 때는 view() 메소드를 사용
  • andExpect(view().name("user"))는 컨트롤러가 리턴한 뷰 이름이 맞는지 검증
  • 이동대상의 경로 검증을 위해서 forwardedUrl() 메소드를 사용.
  • 만약 요청 처리 결과가 리다이렉트 응답이면 redirectedUrl() 메소드를 사용한다. andExpect(redirectedUrl("/user")) 코드는 '/user' 화면으로 리다이렉트했는지 검증

3. 모델 정보 검증

  • 컨트롤러에서 저장한 모델의 정보를 검증하고 싶다면 MockMvcResultMatchers.model() 메소드를 사용
  • attributeExists(String name) : name에 해당하는 데이터가 Model에 포함되어 있는지 검증
  • attribute(String name, Object value) : name에 해당하는 데이터가 value 객체인지 검증

4. 요청/응답 전체 메시지 확인하기

  • 생성된 요청과 응답 메시지를 모두 확인해보고 싶다면 perform 메소드가 리턴하는 ResultAction의 andDo(ResultHandler handler) 메소드를 사용
  • MockMvcResultHandlers.print() 메소드는 ResultHandler를 구현한 ConsolerPrinting ResultHandler 객체를 리턴하여, ConsolePrintingResultHandler를 andDo() 메소드 인자로 넘겨주면 콘솔에 요청/응답과 관련된 정보를 모두 출력

MockMvc 필터 추가

@SpringBootTest
@Transactional
@AutoConfigureMockMvc
class CategoryControllerTest {
    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext ctx;

    private final String baseUrl = "/api/v1/category";

    @BeforeEach
    private void setup() {
        // Response Content 에서 출력시 한글 깨짐 방지
        // 이 방법은 WebApplicationContext를 주입 받아야하므로 @SpringBootTest에서만 사용가능합니다.
        // 혹은 webAppContestSetup 대신에 standAloneSetup 으로 컨트롤러를 지정할수도있음
        this.mockMvc = MockMvcBuilders.webAppContextSetup(ctx)
                .addFilters(new CharacterEncodingFilter("UTF-8", true))  // 필터 추가
                .alwaysDo(print())
                .build();
    }
  • webAppContextSetup
    • 실제 Spring Mvc Configuration을 로딩
    • TestContext framework이 Spring configuration을 캐쉬하기 때문에, 많은 테스트가 있어도 빠르게 테스트를 수행할 수 있음
    • 이때 주입받으려면 @SpringBootTest 또는 @WebAppConfiguration 가 필요
    • 통합 테스트 위주
  • standaloneSetup
    • Spring configuration을 로딩하지 않고 Controller instance를 수동으로 생성
    • 유닛 테스트 위주

23-03-24

Reference