스프링 부트 통합 테스트 환경에서 MockBean 성능 저하 문제
스프링을 사용하는 개발자분들의 대부분은 통합테스트 작성시 @MockBean을 사용하실 것 같습니다.
Mock을 사용하고 통합테스트를 진행시 1개라면 괜찮지만 N개일 경우에는 N번 만큼 Spring context가 reload 를 할 것입니다.
그 이유는 스프링은 @MockBean 설정이 다르거나, @MockBean이 존재하지 않는다면 다른 구성으로 판단 하기 때문입니다.
N번의 reload 이유는 BeanFactory 에서 특정 Bean만 Mocking 객체로 교체하면 되는것이 아니라 해당 Bean을 의존하고 있는 모든 Bean들을 모두 확인 후 교체해서 주입해주어야 하기 때문에 이미 등록된 Context상에서 처리하기에는 어려움이 있는 작업이라고 합니다.
해결 방안
그때의 문제점을 해결하는 것은 만들어 둔 것을 재사용을 하는 것 입니다.
이런 TestSupport 의 환경을 만들어둬서 재 사용을 하 면 N번의 Spring context reload를 막을 수 있습니다.
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
@WebMvcTest(controllers = {
exampleController1.class,
exampleController2.class
})
public abstract class ControllerTestSupport {
@Autowired
protected MockMvc mockMvc;
@Autowired
protected ObjectMapper objectMapper;
@MockBean
protected ExampleService1 exampleService1;
@MockBean
protected ExampleService2 ExampleService2;
}
아래의 예시는 Mail 이나 외부의 의존성을 Test를 확인할 경우 이렇게 MockBean으로 등록을 한 후
재사용을 할 경우 테스트의 시간을 빠르게 단축을 할 수 있습니다.
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ActiveProfiles;
@ActiveProfiles("example")
@SpringBootTest
public abstract class IntegrationTestSupport {
@MockBean
protected MailSendClient mailSendClient;
}