개발일기장

@WebMvcTest 이용해서 컨트롤러 테스트하기

자몽포도 2023. 4. 4. 00:15

목차

1. 지난 날의 나

2. @WebMvcTest

3. @WebMvcTest로 컨트롤러 테스트 하기


지난 날의 나

 

부트 캠프에서는 하루 하루 바쁜 여정을 보냈었다. 이에 더해 나는 테스트 코드는 되도록이면 짜야된다는 생각을 가지고 있었다. 그러다보니 바쁜 여정속에서 무작정 테스트 코드를 짜고 있었다. 나는 모든 테스트 클래스에 아래 3가지 애노테이션을 붙이곤 했다. 

 

그리고 토큰이 필요했기에 모든 테스트 클래스에 @BeforeEach에 회원 가입/로그인 로직을 넣어 토큰 값을 받았다.

그러다보니 테스트 코드에서 냄새가 스멀스멀 올라오기 시작했다. 인증 자체가 중요하지 않은 테스트들도 있다. 그럼에도 불구하고 토큰을 만들어야했고 모든 테스트 클래스에 @SpringBootTest 애노테이션이 붙어 스프링 컨테이너 전체를 로드해야 했다.

 

사용자에게 응답하는 데이터나 상태코드와 같이 컨트롤러만 테스트하고 싶을 때가 있다. 이 때도 @SpringBootTest를 이용하면 되긴하지만 조금 더 효과적으로 할 수 있도록 도와주는 에노테이션이 @WebMvcTest이다.

 


@WebMvcTest

@WebMvcTest는 위 두 어노테이션을 사용하는 것보다 조금 더 가볍게 컨트롤러 레이러를 테스트 할 수 있다. @WebMvcTest가 auto-configuration 해주는 Bean들은 아래와 같다.

 

@Controller, @ControllerAdvice, @JsonComponent, Converter/GenericConverter, Filter, WebMvcConfigurer and HandlerMethodArgumentResolver beans / 중요한 점은 @Component, @Service or @Repository 빈들을 등록하지 않는다는 것이다. 그렇기 때문에 일반적으로 컨트롤러 단을 테스트할 때 @WebMvcTest, @MockBean, Mockito 등을 조합해서 사용한다.

 

TestConifguration 어노테이션과 관련된 자세한 내용은 Test Auto-configuration Annotations에서 볼 수 있다.


@WebMvcTest로 컨트롤러 테스트 하기

 

내가 잘 모르는 것일 수도 있지만 나는 컨트롤러 단을 효과적으로 테스트 하기 위해 3가지 준비물을 준비했다.

1. 컨트롤러 테스트에 공통으로 필요한 빈을 가진 클래스

2. 특정 컨트롤러에서만 필요한 빈을 가진 클래스

3. (상황에 따라) 인증 절차를 생략(야매로)하기 위한 빈

 

 

1. 컨트롤러 테스트에 공통으로 필요한 빈을 가진 클래스

이 클래스는 컨트롤러 공용으로 사용할 예정이다.

 

mockMvc 요청, 응답을 받을 수 있고 응답 값으로 검증도 할 수 있다.

objectMapper 요청을 보낼 때 필요한 RequestBody 객체를 매핑하는 용도

 

 

2. 특정 컨트롤러에서만 필요한 빈을 가진 클래스

 

테스트할 대상이 아닌 빈들은 Mock 객체를 만들어주자. Service의 경우, 필요한 곳이 있어서 빈을 만들어줬다.

LoginFilter는 TestLoginFilter로 컨트롤러 레이어에서 인증이 중요하게 작용하지 않는 곳을 위해 만들었다.

 

3. (상황에 따라) 인증 절차를 생략(야매로)하기 위한 빈

 

원래라면 doFilter 메서드에 세션을 확인하는 등의 절차가 작성되어 있다. 해당 컨트롤러 테스트에서는 인증 여부가 중요하지 않아 바로 다음 필터를 타도록 만들어 주었다.

 

 

이제 테스트 코드를 작성해보자. 아직 ResponseBody가 필요한 테스트가 없긴하지만 해당 테스트만으로 3가지 준비물을 준비한 이유는 충분히 설명히 될 것 같다.

 

데이터 저장 여부, 인증 여부 등이 중요하지 않다. 그저 상황에 따라 상태 코드와 응답 메시지가 잘 출력되면 될 뿐이다.