MockedStatic이란?
MockedStatic<T>은 Mockito에서 static 메서드를 모킹(Mock)할 수 있도록 제공하는 기능이다.
기본적으로 Mockito는 static 메서드를 모킹할 수 없지만, mockStatic(Class<T>)를 사용하면 가능하다.
🚀 MockedStatic을 사용하면 static 메서드의 호출을 가로채서 원하는 동작을 지정할 수 있음.
예를 들어, StaticUtils.getDateTime() 같은 메서드가 항상 특정 값을 반환하도록 만들 수 있음.
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import static org.mockito.Mockito.*;
class StaticMethodTest {
@Test
void staticMethodMocking() {
try (MockedStatic<StaticUtils> mockedStatic = mockStatic(StaticUtils.class)) {
// ✅ static 메서드 모킹
mockedStatic.when(StaticUtils::getDateTime).thenReturn("2025-01-01 12:00:00");
// 테스트 실행
String result = StaticUtils.getDateTime();
// 검증
assertEquals("2025-01-01 12:00:00", result);
// static 메서드가 호출되었는지 확인
mockedStatic.verify(StaticUtils::getDateTime, times(1));
}
}
}
// ✅ 테스트할 Static 클래스
class StaticUtils {
public static String getDateTime() {
return "실제 시스템 시간"; // 실제 코드에서는 현재 시간 반환
}
}
실행 흐름
- mockStatic(StaticUtils.class)을 사용해 StaticUtils.getDateTime()을 모킹.
- mockedStatic.when(StaticUtils::getDateTime).thenReturn("2025-01-01 12:00:00")으로 테스트할 값을 지정.
- 실제 메서드가 호출되면 모킹된 값(2025-01-01 12:00:00)이 반환됨.
- mockedStatic.verify(StaticUtils::getDateTime, times(1))을 통해 정확한 호출 횟수 검증.
MockedStatic의 다양한 사용법
thenAnswer()로 동적 응답 설정
테스트 실행 시 매개변수에 따라 다른 값을 반환하도록 설정할 수도 있다.
try (MockedStatic<MathUtils> mockedStatic = mockStatic(MathUtils.class)) {
mockedStatic.when(() -> MathUtils.calculate(10)).thenReturn(100);
mockedStatic.when(() -> MathUtils.calculate(20)).thenReturn(400);
assertEquals(100, MathUtils.calculate(10));
assertEquals(400, MathUtils.calculate(20));
}
doNothing()으로 void 메서드 처리
void 메서드를 모킹할 경우 doNothing() 또는 thenAnswer()를 사용할 수 있다.
try (MockedStatic<LoggerUtils> mockedStatic = mockStatic(LoggerUtils.class)) {
mockedStatic.when(() -> LoggerUtils.log("INFO", "테스트 로그")).thenAnswer(invocation -> null);
LoggerUtils.log("INFO", "테스트 로그");
mockedStatic.verify(() -> LoggerUtils.log("INFO", "테스트 로그"), times(1));
}
주의할 점
Static Mocking은 반드시 try-with-resources로 감싸야 한다.
왜냐하면 mockStatic()이 글로벌하게 영향을 미치므로, 테스트가 끝나면 반드시 close() 해야 함.
try (MockedStatic<StaticClass> mockedStatic = mockStatic(StaticClass.class)) {
// 테스트 코드
} // ✅ 테스트가 끝나면 자동으로 mock 해제
❌ 이렇게 하면 안 됨!
MockedStatic<StaticClass> mockedStatic = mockStatic(StaticClass.class);
mockedStatic.when(() -> StaticClass.someMethod()).thenReturn("Mocked");
MockedStatic은 static 메서드의 의존성을 줄이고, 특정한 값을 강제로 반환하도록 설정하는 데 유용하다.
하지만 무분별하게 사용하면 유지보수가 어려워지므로 필요한 경우에만 사용해야 한다! 🔥
'TEST' 카테고리의 다른 글
| 테스트 코드를 작성하며 설계의 문제를 발견한 이야기 - 무심코 작성한 코드의 숨은 위험을 찾아내다 (0) | 2025.02.11 |
|---|---|
| 테스트 코드를 작성하며 설계의 문제를 발견한 이야기 - 역할 분리의 중요성 (0) | 2025.01.14 |
| 테스트 코드를 작성하며 설계의 문제를 발견한 이야기 - 데미터의 법칙 (1) | 2025.01.14 |
| 테스트 코드 - 더미 데이터 쉽게 만들기 (Easy Random) 사용하기 (2) (1) | 2024.03.19 |
| 테스트 코드 - 더미 데이터 쉽게 만들기 (Easy Random) 알아보기 (0) | 2023.08.26 |