본문으로 바로가기
반응형

개요

Spring Camp 2023, 김남윤님이 발표하신 실무에서 적용하는 테스트 코드 작성 방법과 노하우 영상을 보며 포스팅으로 정리한 글입니다.

Mock Server 기반 테스트 코드

예를 들어 위와 같은 코드가 있다고 가정해보자. 해당 코드는 PartnerClient라는 클래스를 통해 파트너의 정보를 얻어오는데, 해당 클래스는 외부 통신을 수행하는 클래스이다. 

 

이런 경우 위와 같이 Mock Server를 통해 실제 응답값을 모킹하여 테스트 코드를 작성하곤 한다.

 

그런데 이 때 PartnerClient를 사용하는 클래스가 위처럼 수많이 늘어나면 어떻게 될까? 당연히 모든 테스트마다 Mock Server를 통해 모킹하는 작업이 필요할 것이다. 나아가서 Mock Server가 아닌 @MockBean을 통해 모킹해주는 방법을 생각할수도 있다. 이러한 경우 Mock Server보다 비교적 짧은 코드로 손쉽게 모킹을 수행해줄 수 있다.

하지만 여기서 문제가 발생한다. @MockBean을 통해 실제 띄워진 빈을 모킹하는 경우 Application Context가 초기화되기 때문에 재사용을 할 수 없고, 그에 따라 테스트 코드가 늘어날수록 지연시간이 크게 늘어난다.

 

이를 @TestConfiguration 기반으로 실제 빈으로 등록하는 형태로써 회피할 수 있다. (@Primary는 실제 빈과의 충돌을 막기 위해 우선순위를 지정해준 것이다) 위처럼 실제 빈으로 등록하기 때문에 @MockBean과는 달리 Application Context의 초기화가 발생하지 않고 기존에 띄워둔 Context를 재사용할 수 있게 된다. 

멀티 모듈에서의 테스트 설정 파일 중복 이슈

그렇다면 이제 멀티 모듈로 구성되어있는 상태에서 테스트 코드 작성에 대해 생각해보자. 위 @TestConfiguration으로 생성한 클래스처럼 실제 테스트 코드를 작성할 때에는 테스트를 위한 헬퍼 클래스들을 작성하기 마련이다. 

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(MockitoExtension.class)
@TestEnvironment
public @interface UnitTest {}

실제로 나는 유닛 테스트의 경우 위처럼 Custom한 어노테이션을 생성하여 사용하고 있었다. 그런데 멀티 모듈의 경우 타 모듈에 대해 의존을 설정하면 main 디렉토리에는 접근이 가능하지만 test 디렉토리에는 접근이 불가능하다. 한마디로 import가 불가능하다는 것이다. 이는 java-test-fixtures 의존성을 통해 해결할 수 있다. 

A라는 모듈에 테스트 관련 클래스를 생성해둔 상태에서 B모듈이 A모듈에 의존하는 상황이라면 build.gradle파일에 

// B 모듈

dependencies {
    testApi(testFixtures(project(":A")))
}

위처럼 테스트 관련 의존성을 설정해주면 된다. 그러면 B 모듈에서 A 모듈의 test 디렉토리에 접근할 수 있고 A 모듈에 작성된 테스트 관련 파일을 import하여 사용할 수 있게 된다. (물론 main에는 당연히 접근이 불가능하다)

여기에서 한가지 생각해볼점이 있다. 테스트를 위해 이렇게까지 해줘야하냐는 점이다. 그냥 main 디렉토리에 test 관련 파일을 넣어주면 단순 의존성 설정만으로 접근이 가능한데 말이다. 하지만 이런 경우 휴먼 에러로 인해 test 디렉토리에 있는 클래스를 import하여 사용할 수 있기 때문이다. 여기까지 정리한 내용은 다음과 같다.

 

Reference

https://www.youtube.com/watch?v=XSkz0kO7J3w

 

반응형