Mocking해서 Controller 단위 테스트 하기

minseok·2023년 10월 23일
0

문제

HandlerMethodArgumentResolver에서 반환하는 값을 사용하는 Controller Test를 어떻게 하지?



과정


3가지가 떠오른다.
1. Controller와 관련된 기능 모두 실제 Bean 사용 <- WebMvcTest 사용
2. 최대한 Mocking 하기 <- WebMvcTest 사용
3. WebMvcTest 사용하지 않기

일단 나는 Controller로 들어온 파라미터의 유효성 검사만 하기로 했다.
응답은 Service에서 받은 것을 그대로 패스해서 응답 값은 무시한다.
응답 값을 잘 주는 것은 다른 테스트에서 잘 해준다고 믿고 Controller를 방해되는 요소는 모두 무시하자!

내가 작성한 Controller를 @WebMvcTest를 통해 테스트 하면HandlerMethodArgumentResolver가 테스트에 직접적인 영향을 준다.

@WebMvcTest에서 사용하는 Bean

  • @Controller
  • @ControllerAdvice
  • @JsonComponent
  • Converter/GenericConverter
  • Filter
  • WebMvcConfigurer
  • HandlerMethodArgumentResolver


그리고 지금 코드의 Interceptor, Resolver가 의존하는 여러 컴포넌트가 존재한다.
실제 구현체를 사용하면 Controller 단위 테스트가 영향을 많이 받을 것 같다는 생각이 들어 1번 항목은 제외한다.

아무래도 단순화시켜서 해결하는게 유지보수에도 좋을 것 같다!


테스트 대상이다.
파라미터의 MemberDto는 HandlerMethodArgumentResolver에서 인자로 넘겨준다.

이제 저 값을 Stubbing 하자.
방법은 모킹 라이브러리를 사용하거나 테스트용 객체를 한 개 만드는 것이다.

모킹 라이브러리를 사용하면 쉽게 Stubbing 할 수 있다.
하지만 너무 많은 빈을 의존해서 까다로운 테스트여도
쉽게 목적을 이룰 수 있어서 오히려 좋은 구조에서 멀어진다는 단점이 있다.



이제 문제를 해결해보자

공통 준비물

나는 직접 목업 객체를 만들었지만 모킹 라이브러리를 사용해도 무관하다.

1. MockMVC 직접 만들기

jakarta.validation.constraints.*의 검증 어노테이션이 동작을 안한다.
ArgumentResolver를 직접 넣어준 것 처럼 setValidaiton()으로 넣어줘야 하며
다른 컴포넌트도 직접 넣어줘야 하는 것 같다.

아래는 Spring Docs인데 MockMvc에 대한 Overview이다.



2. Configuration 교체

기존 Config를 exclude하고 테스트용 Config를 Import를 하니깐 잘 동작했다.
나는 CustomInterceptor도 사용하고 있어서 함께 셋업했다.



3. BDDMockito 사용

MemberArgumentResolver를 exclude한 후

목 객체를 Bean으로 넣어준다.

본인 전략에 맞게 Stubbing 해준다.

profile
즐겁게 개발하기

0개의 댓글