Mockito 모의 정적 방법 - PowerMock
Mockito를 사용하면 목 객체를 만들 수 있습니다. 정적 메서드는 클래스에 속하므로 Mockito에서 정적 메서드를 조롱할 방법이 없습니다. 그러나 Mockito 프레임워크와 함께 PowerMock을 사용하여 정적 메서드를 조롱할 수 있습니다.
PowerMock을 사용한 Mockito Mock 정적 방법
PowerMock은 Mockito 및 PowerMock으로 TestNG를 확장하는 다양한 모듈을 제공합니다.
PowerMock 종속성
Mockito에서 정적 메서드를 조롱하려면 다음 PowerMock 종속성이 필요합니다.
powermock-api-mockito2
: 이것은 핵심 PowerMock 종속성이며 Mockito2 모킹 프레임워크를 확장하는 데 사용됩니다. Mockito 1.x 버전을 사용하는 경우powermock-api-mockito
모듈을 사용하세요.powermock-module-junit4
: PowerMock을 사용하여 JUnit 4 테스트 사례를 실행합니다.powermock-module-testng
: TestNG 테스트 사례를 실행하고 PowerMock을 지원합니다.
아래는 우리 프로젝트의 최종 pom.xml입니다.
<project xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev.powermock</groupId>
<artifactId>PowerMock-Examples</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<testng.version>6.14.3</testng.version>
<junit4.version>4.12</junit4.version>
<mockito-core.version>2.19.0</mockito-core.version>
<powermock.version>2.0.0-beta.5</powermock.version>
<java.version>10</java.version>
</properties>
<dependencies>
<!-- TestNG -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
<!-- JUnit 4 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit4.version}</version>
<scope>test</scope>
</dependency>
<!-- Mockito 2 -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito-core.version}</version>
<scope>test</scope>
</dependency>
<!-- PowerMock TestNG Module -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-testng</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<!-- PowerMock JUnit 4.4+ Module -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<!-- PowerMock Mockito2 API -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.22.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-testng</artifactId>
<version>2.22.0</version>
</dependency>
</dependencies>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>src/test/java/</additionalClasspathElement>
</additionalClasspathElements>
<!-- TestNG Test Fails when executed from command line with message
"Cannot use a threadCount parameter less than 1"
Works when threadCount is explicitly specified
https://gist.github.com/juherr/6eb3e93e2db33979b7e90b63ddadc888-->
<threadCount>5</threadCount>
</configuration>
</plugin>
</plugins>
</build>
</project>
PowerMock의 2.0.0-beta.5
버전을 사용하고 있습니다. 이 버전은 Java 10을 지원하지만 아직 베타 버전이므로 복잡한 경우 몇 가지 문제가 있을 수 있습니다. 현재 안정 버전 1.7.x
를 사용하려고 했을 때 다음과 같은 오류가 발생했습니다.
java.lang.NoSuchMethodError: org.mockito.internal.handler.MockHandlerFactory.createMockHandler(Lorg/mockito/mock/MockCreationSettings;)Lorg/mockito/internal/InternalMockHandler;
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMethodInvocationControl(DefaultMockCreator.java:114)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMock(DefaultMockCreator.java:69)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.mock(DefaultMockCreator.java:46)
at org.powermock.api.mockito.PowerMockito.mockStatic(PowerMockito.java:73)
다음은 이 예외(issue2)에 대해 열린 GitHub 문제입니다. 정적 메서드로 간단한 클래스를 만들어 봅시다.
package com.journaldev.mockito.staticmethod;
public class Utils {
public static boolean print(String msg) {
System.out.println("Printing "+msg);
return true;
}
}
JUnit Mockito PowerMock 예제
PowerMock을 Mockito 및 JUnit 4와 통합하려면 다음을 수행해야 합니다.
@RunWith(PowerMockRunner.class)
주석으로 테스트 클래스에 주석을 답니다.@PrepareForTest
로 테스트 클래스에 주석을 달고 PowerMock을 사용하여 조롱할 클래스를 제공합니다.PowerMockito.mockStatic()
을 사용하여 정적 메소드로 클래스를 조롱하십시오.PowerMockito.verifyStatic()
을 사용하여 Mockito를 사용하여 모의 메서드를 확인합니다.
다음은 JUnit 테스트 케이스에서 Mockito 및 PowerMock을 사용하여 정적 메서드를 조롱하는 완전한 예입니다.
package com.journaldev.mockito.staticmethod;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.when;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(Utils.class)
public class JUnit4PowerMockitoStaticTest{
@Test
public void test_static_mock_methods() {
PowerMockito.mockStatic(Utils.class);
when(Utils.print("Hello")).thenReturn(true);
when(Utils.print("Wrong Message")).thenReturn(false);
assertTrue(Utils.print("Hello"));
assertFalse(Utils.print("Wrong Message"));
PowerMockito.verifyStatic(Utils.class, atLeast(2));
Utils.print(anyString());
}
}
TestNG Mockito PowerMock 예제
TestNG 테스트 사례의 경우 @RunWith
주석을 사용할 필요가 없습니다. PowerMockObjectFactory
가 테스트 클래스 인스턴스를 만드는 데 사용되도록 PowerMockTestCase
를 확장하려면 테스트 클래스가 필요합니다.
package com.journaldev.mockito.staticmethod;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.mockito.Mockito.*;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.annotations.Test;
@PrepareForTest(Utils.class)
public class TestNGPowerMockitoStaticTest extends PowerMockTestCase{
@Test
public void test_static_mock_methods() {
PowerMockito.mockStatic(Utils.class);
when(Utils.print("Hello")).thenReturn(true);
when(Utils.print("Wrong Message")).thenReturn(false);
assertTrue(Utils.print("Hello"));
assertFalse(Utils.print("Wrong Message"));
PowerMockito.verifyStatic(Utils.class);
Utils.print("Hello");
PowerMockito.verifyStatic(Utils.class, times(2));
Utils.print(anyString());
}
}
요약
PowerMock은 Mockito에 대한 확장 기능을 제공하며 그 중 하나는 정적 메서드를 테스트하는 기능입니다. JUnit 4 및 TestNG와 쉽게 통합됩니다. 그러나 JUnit 5에 대한 단기 지원 계획은 없습니다.
GitHub 리포지토리에서 전체 프로젝트를 다운로드할 수 있습니다.