개발 등/SPRING

@WebMvcTest VS @AutoConfigureMockMvc

darkhorizon 2023. 4. 26. 21:25
728x90
반응형

스프링 부트에서 컨트롤러단의 테스트 클래스를 작성하기 위해서 보통 @SpringBootTest + @AutoConfigureMockMvc 어노테이션으로 작업을 하는 경우가 많다.

@SpringBootTest를 이용해서 테스트를 작성하게 되면 스프링 빈을 모두 로드하기 때문에 통합테스트가 아닌 경우에 적합하지 않다. 특히 컨트롤러단의 테스트를 위해서는 Web Layer에 필요한 요소만 로드할 수 있는 테스트 방식이 더 적합하다.

이럴 경우 @WebMvcTest(로드할 컨트롤 클래스) 어노테이션을 사용한다.

 

@WebMvcTest(EventController.class)
public class EventControllerTests {
    @Autowired
    MockMvc mockMvc;

    @Test
    void createEvent() throws Exception {
        mockMvc.perform(post("/api/events")
                        .contentType(MediaType.APPLICATION_JSON_UTF8)
                        .accept(MediaTypes.HAL_JSON))
                .andDo(print())
                .andExpect(status().isCreated());
    }
}

 

이 경우 WebApplication과 관련된 스프링 빈들만 등록하기 때문에 훨씬 가볍고 빠르다.

그리고 단위테스트가 가능하다는 장점이 있다.

반대로 Mock 기반 테스트이기 때문에 실제 환경에서는 예상 외의 오류가 발생할 가능성도 있다는 점이다.


Web Layer가 아닌 Service나 Repository의 빈을 사용해야 할 경우엔 @MockBean 어노테이션을 이용하면 된다.

 

    @MockBean   // @WebMvcTest로 Web Layer의 슬레이스테스트라 Repository 빈은 못들고 오기 때문에 MockBean으로 등록
    EventRepository eventRepository;
    
	@Test
    void createEvent() throws Exception {
        Event event = Event.builder()
                .name("spring")
                .build();
        event.setId(10);
        // 목빈의 해당 메서드 이벤트가 발생할 때, 임의의 객체 리턴
        Mockito.when(eventRepository.save(event)).thenReturn(event);    

        mockMvc.perform(post("/api/events")
                        .contentType(MediaType.APPLICATION_JSON_UTF8)
                        .accept(MediaTypes.HAL_JSON)
                        .content(objectMapper.writeValueAsString(event)))
                .andExpect(status().isCreated())
                .andExpect(jsonPath("id").exists());
    }

 

728x90