먼저 static method를 모킹하는 방법에 대해 소개하고 wrapper로 활용해 psa를 만족하는 방법을 소개하겠다.
Mockito로 static method를 모킹할려고 하면 해당 static method를 모킹 할 수 없는거에 당황을 하게 된다. 이럴때 테스트를 위해서는 기본적으로 두가지 방법이 있다.
우선 테스트 대상의 코드 중 static method를 호출하는 부분은 다음과 같다.
static method ->
BearerTokenResolver.resolve(request)
직접 static method를 모킹하는게 아니라 static method의 인수값을 모킹해 원하는 결과를 유도하는 방법이다.
앞서 본 코드에서 모킹할려는 BearerTokenResolver.resolve(request)
의 호출부분을 보면 테스트 대상인 doFilterinternal(request, response, doFilter)
의 인수인 request
를 가져와 쓴다는 걸 확인할 수 있다.
그러면 doFilterinternal
의 request
를 잘 만들면 static method의 동작을 유도할 수 있다.
테스트코드
static method의 인수인 request
를 모킹한다
모킹한 request
를 넘긴다.
하지만 위 상황에서는 resolve
메소드가 내부에서 request
를 어떻게 사용하는지 알기 힘든 경우가 있다. 이럴떄는 직접 resolve 코드를 분석해 코드를 이해한 후 적절한 request
값을 넣어 주어야 한다.
LocalDate.now()
처럼 인수 값이 존재하지 않을 경우 이 방법은 불가능 하다(물론 실제론 LocalDate.now()
는 인수 값이 있는 LocalDate.now(clock)
메소드도 제공한다).
Mockito에서 지원하는 static mock 기능을 사용하는 방법이다.
모킹한 static method가 프로젝트 전체에서 모킹 동작을 한다. 그래서 테스트가 끝난 후 MockedStatic를 해제한다. 위 코드에서는 bearerTokenResolver.close()
로 모킹한 static method를 해제할 수 있으며, 위 코드에서 처럼 java 문법인 try-with-resources
를 활용해 해제해 주었다.
모킹하지 않고 static method인 BearerTokenResolver
클래스를 추상화해 사용하는 방법이다. 이 방법은 테스트 대상의 코드를 변경 해야한다.
방법은 다음과 같다.
테스트 하려는 static method와 같은 인스턴스 method를 가지는 interface를 선언한다.
앞에서 만든 interface를 구현해 static method를 감싸는 인스턴스 method를 가진 클래스를 만든다.
전
후
이제 원하는 대로 모킹해서 원하는 대로 static method를 모킹할 수 있다.
기존 BearerTokenResolver
만 있던 구조에서
BearerTokenResolver
를 추상화한 interface를 만들고 기존 코드를 감싸는 DefaultTokenResolver
를 만들었다.
백기선유튜브-스프링 제대로 공부했는지 5분안에 확인하는 방법