我想在junit5中模拟静态方法。但不幸的是,Junit5不支持Powermockito。除了恢复到Junit4之外,还有其他方法可以实现相同目的吗?
答案 0 :(得分:9)
从Mockito 3.4.0(2020年7月10日)开始,甚至可以在 JUnit 5 中对开箱即用的静态方法进行模拟,而无需任何扩展。
在文档中,您可以找到一个示例:https://javadoc.io/static/org.mockito/mockito-core/3.4.6/org/mockito/Mockito.html#static_mocks
重要说明:您需要使用内嵌模拟制作器。因此,要使用的依赖项不是核心的依赖项:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.4.6</version>
<scope>test</scope>
</dependency>
示例: 被测课程:
package teststatics;
public class FooWithStatics {
public static Long noParameters() {
return System.currentTimeMillis();
}
public static String oneParameter(String param1) {
return param1.toUpperCase();
}
}
测试类:
package teststatics;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
public class FooWithStaticsTest {
@Test
void testStatic() {
// before mock scope, usual behavior.
assertNotEquals(0L, FooWithStatics.noParameters());
assertNotEquals("yyy", FooWithStatics.oneParameter("xxx"));
// Mock scope
try (MockedStatic mocked = mockStatic(FooWithStatics.class)) {
// Mocking
mocked.when(FooWithStatics::noParameters).thenReturn(0L);
mocked.when(() -> FooWithStatics.oneParameter("xxx")).thenReturn("yyy");
// Mocked behavior
assertEquals(0L, FooWithStatics.noParameters());
assertEquals("yyy", FooWithStatics.oneParameter("xxx"));
// Verifying mocks.
mocked.verify(times(1), FooWithStatics::noParameters);
mocked.verify(times(1), () -> FooWithStatics.oneParameter("xxx"));
}
// After mock scope returns to usual behavior.
assertNotEquals(0L, FooWithStatics.noParameters());
assertNotEquals("yyy", FooWithStatics.oneParameter("xxx"));
}
}
答案 1 :(得分:3)
Mockito目前不提供静态方法模拟的原因是因为人们普遍认为静态方法不需要模拟。 但是,mockito here的一个开放项目讨论了该问题。 虽然这不能回答您的问题,但通常可以告诉您为什么根本不需要该功能,或者为什么您可以将自己的想法加入对话。
答案 2 :(得分:3)
回答不多,因为PowerMockito团队已经完成了他们的work的工作,并等待JUnit团队进行extension的讨论,并在这里进行了很多讨论。
有一些开销,您可以:由于JUnit5提供了运行旧版JUnit4的支持,因此您可以使用PowerMockito。因此,您可以在Junit4中针对以下情况创建测试: 使用gradle和mvn进行迁移设置的示例项目。 从那里开始,我将PowerMock 2.0 beta与Mockito2结合使用。
答案 3 :(得分:0)
确保在你的 POM 文件中有 mockito-inline 依赖
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.6.28</version>
<scope>test</scope>
</dependency>
在我的情况下,我必须测试抛出异常的场景,URLEncoder 类的静态方法 encode(),因此
try (MockedStatic theMock = mockStatic(URLEncoder.class)) { theMock.when(() -> URLEncoder.encode("Test/11",StandardCharsets.UTF_8.toString())) .thenThrow(UnsupportedEncodingException.class); when(restClient.retrieveByName("Test%2F11")).thenReturn(null); Assertions.assertThrows(ResponseStatusException.class,()->service.retrieveByName("Test/11")); }