我想在JUnit 5中模拟一个静态方法。但不幸的是,JUnit 5不支持Mockito。除了恢复到JUnit 4之外,还有其他方法可以实现相同的效果吗?
r1zhe5dt1#
从Mockito 3.4.0(2020 - 07 - 10)开始,即使在JUnit 5中也可以模拟开箱即用的静态方法,而无需任何扩展。在文档中,您可以找到一个示例:* 48.模拟静态方法(3.4.0以后)*重要提示:您需要使用 * inline mock maker *。因此要使用的依赖项不是核心依赖项:
<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")); } }
axr492tv2#
简短的回答是否定的,因为Mockito团队已经完成了他们的work,正在等待JUnit团队提供extension,并且在这里讨论了很多。通过一些开销,您可以:由于JUnit 5支持运行遗留的JUnit 4,因此您可以使用Mockito。因此,您可以在Junit4中为以下情况创建测试:使用gradle和mvn进行迁移设置的示例项目。从那里我将使用PowerMock 2.0 beta和Mockito 2。
vnjpjtjt3#
Mockito目前不提供静态方法mocking的原因是因为人们普遍认为静态方法不需要被mocking。但是,Mockito here有一个讨论该问题的开放项目。虽然这并没有回答你的问题,但总的来说,它告诉你为什么你根本不需要这个功能,或者允许你加入讨论,提出你的想法。
7rfyedvj4#
1.确保POM文件中具有mockito-inline依赖关系
mockito-inline
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-inline</artifactId> <version>3.6.28</version> <scope>test</scope> </dependency>
1.在我的例子中,我必须测试异常抛出URLEncoder类的静态方法encode()的场景,因此
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")); }
y53ybaqx5#
我们可以使用JMockit模拟静态方法。JMockit用于模拟测试边界之外的外部依赖,类似于Mockito和其他类似的模拟库,JMockit最重要的特性是允许我们模拟任何东西,甚至是其他库难以模拟的东西,如构造函数、静态方法和最终方法,甚至允许模拟成员字段和初始化块。
按照以下步骤启用JMockit:
<!-- https://mvnrepository.com/artifact/org.jmockit/jmockit --> <dependency> <groupId>org.jmockit</groupId> <artifactId>jmockit</artifactId> <version>1.49</version> <scope>test</scope> </dependency>
1.在TestClass中模拟Class方法:
public class TestClass{ @Test public void testMethod() { new MockUp<ClassName>(){ @Mock //mock the method here }; }
}请按照教程了解有关如何使用JMockit的更多信息。
5条答案
按热度按时间r1zhe5dt1#
从Mockito 3.4.0(2020 - 07 - 10)开始,即使在JUnit 5中也可以模拟开箱即用的静态方法,而无需任何扩展。
在文档中,您可以找到一个示例:* 48.模拟静态方法(3.4.0以后)*
重要提示:您需要使用 * inline mock maker *。因此要使用的依赖项不是核心依赖项:
示例:受试类:
测试类别:
axr492tv2#
简短的回答是否定的,因为Mockito团队已经完成了他们的work,正在等待JUnit团队提供extension,并且在这里讨论了很多。
通过一些开销,您可以:由于JUnit 5支持运行遗留的JUnit 4,因此您可以使用Mockito。因此,您可以在Junit4中为以下情况创建测试:
使用gradle和mvn进行迁移设置的示例项目。从那里我将使用PowerMock 2.0 beta和Mockito 2。
vnjpjtjt3#
Mockito目前不提供静态方法mocking的原因是因为人们普遍认为静态方法不需要被mocking。
但是,Mockito here有一个讨论该问题的开放项目。
虽然这并没有回答你的问题,但总的来说,它告诉你为什么你根本不需要这个功能,或者允许你加入讨论,提出你的想法。
7rfyedvj4#
1.确保POM文件中具有
mockito-inline
依赖关系1.在我的例子中,我必须测试异常抛出
URLEncoder
类的静态方法encode()
的场景,因此y53ybaqx5#
我们可以使用JMockit模拟静态方法。
JMockit用于模拟测试边界之外的外部依赖,类似于Mockito和其他类似的模拟库,JMockit最重要的特性是允许我们模拟任何东西,甚至是其他库难以模拟的东西,如构造函数、静态方法和最终方法,甚至允许模拟成员字段和初始化块。
按照以下步骤启用JMockit:
1.在TestClass中模拟Class方法:
}
请按照教程了解有关如何使用JMockit的更多信息。