[첫번째 프로젝트] 6. @WebMvcTest와 @SpringBootTest 차이

DAEILLIM·2024년 1월 20일
0

첫번째 프로젝트

목록 보기
6/17
post-thumbnail

Junit 테스트 시에 @WebMvcTest@SpringBootTest를 대표적으로 사용하는데, 두 가지 Test 어노테이션의 차이가 존재한다고 한다. SpringBoot 테스트 시에 두 가지 어노테이션의 차이를 살펴보자.

1. Mock, MockMvc

먼저 MockMockMvc에 대해서 알아보자.

1.1 Mock

실제 객체를 만들어서 테스트하기가 어려운 경우에, 가짜 객체를 만들어서 테스트하는 기술이다.

1.2 MockMvc

MVC에 관련된 Mock 가짜 객체를 말한다. 웹 어플리케이션을 애플리케이션 서버에 배포하지 않고, 테스트용 MVC 환경을 만들어서 요청 및 전송, 응답 기능을 제공해주는 객체이다. 대부분의 어플리케이션 기능을 테스트하기 위해서는 MockMvc 객체를 만들어서 테스트하게 되는데, MockMvc@Autowired로 주입받아서 사용할 수 있다.

이렇게 MockMvc@Autowired로 주입 받을 때 두 어노테이션의 차이가 존재한다. 또한, 빈의 등록 범위에도 차이가 존재한다.

구체적으로 차이를 살펴보자.

2. Mock 주입 시 차이

2.1 @SpringBootTest

@SpringBootTest
class SpringBootTest {
    @Autowired MockMvc mockMvc; // 주입 X
}

👉 이렇게 @SpringBootTest만 선언하고, MockMvc를 @Autowired로 주입받으려고 하면, 주입이 되지 않아 오류가 발생한다. 주입이 되지 않는 이유는 간단하다. @SpringBootTest는 MockMvc를 빈으로 등록시키지 않기 때문이다. 따라서, MockMvc를 빈으로 등록하는 과정 필요하다.

이러한 과정은 @AutoConfigureMockMvc 어노테이션을 선언하면 된다.

@SpringBootTest
@AutoConfigureMockMvc
class SpringBootTest {
    @Autowired MockMvc mockMvc; // 주입 O
}

👉 결과적으로, @SpringBootTest에서 MockMvc 객체를 사용하려면, @AutoConfigureMockMvc 어노테이션을 함께 선언해야 한다.

2.2 @WebMvcTest

@WebMvcTest
class SpringBootTest {
    @Autowired MockMvc mockMvc; // 주입 O
}

👉 @WebMvcTest는 MockMvc를 빈으로 등록하기 때문에, @WebMvcTest만 선언해줘도, MockMvc 객체가 주입되게 된다.

3. Bean 등록 범위 차이

3.1 @SpringBootTest

@SpringBootTest
class SpringBootTest {
    @Autowired MockMvc mockMvc; // 주입 O
    @Autowired UserController userController; // 주입 O
    @Autowired UserRepository userRepository; // 주입 O
    @Autowired UserService userService; // 주입 O
}

👉 @SpringBootTest에서는 프로젝트의 컨트롤러, 리포지토리, 서비스@Autowired로 다 주입된다.

3.2 @WebMvcTest

@WebMvcTest
class SpringBootTest {
    @Autowired MockMvc mockMvc; // 주입 O
    @Autowired UserController userController; // 주입 O
    @Autowired UserRepository userRepository; // 주입 X
    @Autowired UserService userService; // 주입 X
}

👉 @WebMvcTest에서는 Web Layer 관련 빈들만 등록하기 때문에, 컨트롤러는 주입이 정상적으로 되지만, @Component로 등록된 리포지토리와 서비스는 주입이 되지 않는다. 따라서, @WebMvcTest에서 리포지토리와 서비스를 사용하기 위해서는 @MockBean을 사용하여 리포지토리와 서비스를 Mock 객체에 빈으로 등록해줘야 한다.

※ Web Layer에 속한 항목들 ※

Security, Filter, Interceptor, request/response Handling, Controller
@WebMvcTest
class SpringBootTest {
    @Autowired MockMvc mockMvc; // 주입 O
    @Autowired UserController userController; // 주입 O
    @MockBean UserRepository userRepository; // 주입 O -> @MockBean 
    @MockBean UserService userService; // 주입 O -> @MockBean 
}

4. @SpringBootTest@WebMvcTest 차이 결론

4.1 @SpringBootTest

  1. MockMvc 객체를 빈으로 등록하지 않기 때문에 @AutoConfigureMockMvc로 빈으로 등록해야한다.
  2. 프로젝트에 있는 스프링 빈을 모두 등록해서 테스트에 필요한 의존성을 추가해준다.

@SpringBootTest 장점

1. 프로젝트에 있는 모든 스프링 빈을 등록하므로, 테스트에 필요한 객체를 주입받아서 쉽게 사용 가능하다.
2. 실제 환경과 가장 유사하게 테스트가 가능하다.

@SpringBootTest 단점

1. 모든 스프링 빈을 등록할 때 프로젝트의 전체 컨텍스트를 로드해서 빈을 주입하기 때문에 속도가 느리다.
2. 테스트 단위가 크기 때문에 디버깅이 어려울 수 있다.

💡 단위 테스트와 같은 기능 테스트가 아닌, 전체적인 프로그램 작동이 제대로 이루어 지는지 검증하는 통합 테스트 시에 많이 사용한다!

4.2 @WebMvcTest

  1. MockMvc 객체를 빈으로 등록해서 @Autowired로 MockMvc 주입이 가능하다.
  2. Web Layer 관련 빈들만 등록하기 때문에, @Component로 등록한 빈은 @MockBean으로 등록해야한다.

@WebMvcTest 장점

1. Web Layer 관련 빈만 로드하기 때문에, 속도가 @SpringBootTest보다 빠르다.
2. 통합테스트에서 테스트가 어려운 작은 단위 테스트들을 @WebMvcTest로 진행할 수 있다.

@WebMvcTest 단점

1. Mock 객체를 사용하기 때문에 실제 환경에서는 다른 오류가 발생할 수 있다.

💡 이러한 이유로, 컨트롤러 테스트, 단위 테스트 시에 많이 사용한다!

profile
필기하고, 타이핑하고, 말하면서 읽고, 코딩하고, 눈으로 읽고 오감으로 공부하기

0개의 댓글