본문 바로가기
SPRING

[SPRING] @WebMvcTest의 Controller테스트

by steadyMan 2022. 9. 18.

@WebMvcTest는 오로지 Controller계층에 대한 테스트를 할 때 사용하는 Controller를 위한 테스트 어노테이션으로 

Scan의 대상이 제한되어 통합 테스트보다 가볍고 빠르게 Controller계층의 테스트가 가능하다.


@WebMvcTest Scan의 대상 

  • @Controller
  • @ControllerAdvice
  • @JsonComponent
  • Converter
  • GenericConverter
  • Filter
  • WebMvcConfigurer, HandlerMethodArgumentResolver
  • WebSecurityConfigurerAdapter

MockMvc의 주입을 지원하여 MockMvc를 활용한 HTTP 요청을 바로 사용할 수 있다. 

// 테스트 대상 Controller
@WebMvcTest(controllers = GameController.class)
public class GameControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Test
    ....
}

요청한 URL에 대한 View 테스트

  • Response Status 코드를 확인
  • 호출된 View의 이름확인 
@Test 
public void gameRegistPageTest() throws Exception{
    mockMvc.perform(get("/admin/game/regist")) // 지정위치에 Get요청을 보낸다.
           .andDo(print()) // 요청내용 print
           .andExpect(status().isOk()) // 응답 status코드 200 확인 
           .andExpect(MockMvcResultMatchers.view().name("game/gameRegist")); // 응답된 view 페이지 확인
}

요청한 URL에 대한 View와 Model 데이터 테스트 

  • Model에 특정 Key의 데이터 존재 여부 확인
  • Model에 담긴 데이터의 타입 확인 
@Test
public void game() throws Exception{
    //given
    String gameId = "12315";
    GameListVO gameListVO =  new GameListVO(12315L, "gameName", "kimId", null, "Y", new Timestamp(new Date().getTime()), null, 1244L, "Y");
    given(gameService.getGame("12315")).willReturn(gameListVO); // Controller에서 gameService.getGame()이 호출될 경우 작성한 객체가 리턴되도록 설정

    //when
    mockMvc.perform(get("/admin/game/{gameId}", gameId)) // pathvariable
           .andExpect(status().isOk())
           .andExpect(view().name("game/gameHome"));
           //model()를 통해 model에 담겨있는 데이터의 타입, 데이터크기 등 다양한 테스트가 가능하다.
           .andExpect(model().attributeExists("gameInfo")) // Model에 "gameInfo"라는 Key가 있는지 확인
           .andExpect(model().attribute("gameInfo", gameListVO)) // "gameInfo"라는 key의 Value 데이터 확인           

    //then
    verify(gameService).getGame("12315"); // gameService 인스턴스의 getGame()메소드가 호출됐는지 확인
}

요청한 URL에 파라미터를 포함하여 전송하고 리다이렉트 여부 확인 

  • URL에 파라미터와 함께 요청
  • Header에 Location 속성 데이터 확인
@Test
public void gameReturn() throws Exception{
    //when
    mockMvc.perform(get("/admin/gameLocation")
                .param("gameId", "1426") // key : gameId Value : 1426의 parameter 전송
                .contentType(MediaType.APPLICATION_FORM_URLENCODED)) // POST전송이므로 Body에 입력
           .andExpect(status().is3xxRedirection()) // 302 redirect Status 코드 확인
           .andExpect(header().string("Location", "/")); // header에 Location 속성 확인
}

요청한 URL의 리턴타입(JSON)의 데이터 테스트

  • Response ContentType 속성 확인
  • Json데이터의 Key 존재 여부 확인
  • Json데이터의 Key값 Value 확인
@Test
public void gameReturn() throws Exception{
    mockMvc.perform(get("/admin/gameInfo/" + "2415"))
           .andExpect(status().isOk())
           .andExpect(content().contentType("application/json")) // Response ContentType 확인
           .andExpect(jsonPath("$.gameId").exists()) // key : gameId 존재여부 확인
           .andExpect(jsonPath("$.gameId").value("2415")) // key gameId 의 value 데이터 확인
           .andDo(print());
}

참고

  • https://www.youtube.com/watch?v=SFVWo0Z5Ppo&t=1345s
  • https://goessner.net/articles/JsonPath/
  • https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTest.html

 

 

댓글