JUnit으로 테스트 작성 시 Static Class를 Mocking해서 테스트를 해야할 경우가 많이 생긴다. sprin-boot-starter-test 패키지에서 기본으로 제공하는 mockito-core패키지에는 static class mocking을 위해 아래 함수를 제공한다.
MockedStatic<SecurityUtils> mockSecurityUtils = Mockito.mockStatic(SecurityUtils.class);
mockSecurityUtils.when(() -> getPlainCredential(anyString(), any())).thenReturn("1q2w3e4r5t!!");
Mokito.mockStatic 메소드에 Mocking을 할 static class를 지정해 주고 when, thenReturn으로 상황에 따른 출력값을 지정해 준다. 그러나 위 기본 제공 메소드를 실행해 보면 다음과 같은 에러가 발생한다.
예제 테스트 코드 실행
@SpringBootTest(properties = {"spring.profiles.active=dev"})
@ContextConfiguration
public class TestCustomer {
@Test
public void insertTest() {
MockedStatic<SecurityUtils> mockSecurityUtils = Mockito.mockStatic(SecurityUtils.class);
mockSecurityUtils.when(() -> getPlainCredential(anyString(), any())).thenReturn("1q2w3e4r5t!!");
}
}
실행 결과
Mockito's inline mock maker supports static mocks based on the Instrumentation API.
You can simply enable this mock mode, by placing the 'mockito-inline' artifact where you are currently using 'mockito-core'.
Note that Mockito's inline mock maker is not supported on Android.
at com.sdp.service.job.sec.TestCustomer.insertTest(TestCustomer.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
대층 해석해보면 static mock mode를 enable 하려면 mockito-inline으로 artifact를 replacing하면 된다고 한다.
간단하게 pom.xml에 위 mockito-inline을 추가해 주면 위 에러는 사라지고 정상적으로 static mocking이 동작하게 된다.
아래와 같이 pom.xml에 추가해 준다.
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
추가로 더 고려해야할 사항은 한번 static mock을 설정해 놓으면 다른 테스트 코드에서 동일하게 static mock 사용 시 이미 사용중이라고 실행이 안된다. 따라서 테스트 코드 작성 시 try 구문을 사용해 테스트 코드 종료시 static mocking 설정이 자동 해제 되도록 하면 전체 테스트 코드 실행시에 다른 테스트에 영향 없이 static mocking을 각 테스트 코드마다 자유롭게 사용할 수 있게 된다.
아래 예는 try구문으로 static mocking 선언을 감싼 결과 이다.
@SpringBootTest(properties = {"spring.profiles.active=dev"})
@ContextConfiguration
public class TestCustomer {
@Test
public void insertTest() {
try (MockedStatic<SecurityUtils> mockSecurityUtils = Mockito.mockStatic(SecurityUtils.class)) {
mockSecurityUtils.when(() -> getPlainCredential(anyString(), any())).thenReturn("1q2w3e4r5t!!");
//assert로 확인
}
}
}
-- The End --
'Backend Development > Spring boot' 카테고리의 다른 글
[Spring boot] Tomcat (windows) + War 배포 하기 (0) | 2022.09.09 |
---|---|
[Spring boot] Exception에 따라 조건부로 Transaction Rollback 하기 (0) | 2022.08.28 |
[Spring boot] Spring Boot Test Sql script 활용하기 (0) | 2022.07.08 |
[Spring boot] Spring boot test H2 DB 사용하기 (0) | 2022.07.08 |
[Spring Boot] swagger ui HTML문서로 출력하기 (1) | 2022.06.22 |