TEST

테스트 코드 작성 시 Mockito로 static 메서드 모킹하기

류큐큐 2025. 2. 14. 10:28

 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 "실제 시스템 시간"; // 실제 코드에서는 현재 시간 반환
    }
}

 

 

 실행 흐름

  1. mockStatic(StaticUtils.class)을 사용해 StaticUtils.getDateTime()을 모킹.
  2. mockedStatic.when(StaticUtils::getDateTime).thenReturn("2025-01-01 12:00:00")으로 테스트할 값을 지정.
  3. 실제 메서드가 호출되면 모킹된 값(2025-01-01 12:00:00)이 반환됨.
  4. 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 메서드의 의존성을 줄이고, 특정한 값을 강제로 반환하도록 설정하는 데 유용하다.
하지만 무분별하게 사용하면 유지보수가 어려워지므로 필요한 경우에만 사용해야 한다! 🔥