java - 当调用多个静态方法时,使用 Mockito 验证静态方法调用
问题描述
我正在尝试验证在测试期间是否调用了静态方法。但是,由于在运行期间调用了同一类的多个静态方法,因此它会引发异常。这两种静态方法都是模拟的。确切的例外是这样的:-
验证静态存根时发生意外错误。
要正确验证存根,请在提供的 lambda 中调用 com.booking.capacityservicejobs.models.YourStaticClass 的单个静态方法。
例如,如果定义了方法“sample”,请提供包含代码的 lambda 或匿名类。
代码是这样的: -
try (MockedStatic<MyClass1> theMock = Mockito.mockStatic(MyClass1.class);
MockedStatic<MyClass2> configMock = Mockito.mockStatic(MyClass2.class);
MockedStatic<MyClass3> downtimeMock = Mockito.mockStatic(MyClass3.class)) {
theMock.when(MyClass1::lockAndFetch).thenReturn(duRuns);
theMock.when(() -> MyClass1.startAndUnlock(1)).thenAnswer(invocation -> null);
configMock.when(() -> MyClass2.getById(1)).thenReturn(dummyConfig);
downtimeMock.when(() -> MyClass3.isScheduledForRole("app-dummy")).thenReturn(false);
new RunExecutor().run(); //this executes the code to be tested
theMock.verify(() -> MyClass1.startAndUnlock(1));
}
我可以在不使用 powermock 的情况下绕过这个限制吗?验证多个(不同)静态方法调用的正确方法是什么?
解决方案
即使我同意这不是一个好的做法,我也不得不自己处理这个问题,因为我对库中的静态实用程序类有依赖关系,我无法重构它,所以我的答案是这样。
我的情况与您的情况不完全一样:我正在测试一个方法,该方法HttpUtils.logProtocolMessages
内部调用了LoggingApi
实用程序类中的 2 个不同的静态方法;两种方法都返回无效。这对我有用:
@Test
public void logProtocolMessageWithoutRequestTest() {
try (MockedStatic<LoggingApi> mockLog = Mockito.mockLog(LoggingApi.class)){
mockLog.when(() -> {
LoggingApi.setProtocolSendMessage(anyString(), anyString());
LoggingApi.setProtocolReceiveMessage(anyString(), anyString(), anyString());
}).thenAnswer(Answers.RETURNS_DEFAULTS);
HttpUtils.logProtocolMessages(mockTarget, HttpClientVersion.HTTP_2, response, null);
mockLog .verify(() -> JcatLoggingApi.setProtocolSendMessage(anyString(), anyString()));
mockLog .verify(() -> LoggingApi.setProtocolReceiveMessage(anyString(), anyString(), anyString()));
}
}
如您所见,这 2 个静态方法在同一个 lambda 中被模拟,它们都被指示不返回任何内容。我想说,任何超出此范围的案例都应该考虑重新设计(如果可能的话),甚至是测试本身。
这仅适用于使用 verify 的基本验证,例如调用模拟方法的 # 次。如果您尝试进行更复杂的检查,例如捕获参数,则在 lambda 中调用单个静态方法的限制将占上风,并且任何基于捕获者的断言都将失败,因为 Mockito 无法在多个时正确注入它们的值调用同一模拟静态类中的方法。
这是我使用的模拟依赖项:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.1.0</version>
<scope>test</scope>
</dependency>
推荐阅读
- amazon-web-services - AWS EC2 实例的访问策略
- python - 我们如何比较 django 中的请求对象?
- pytorch - 导出一个 torchscript 模型
- javascript - Passport.js - 自定义未经授权的消息
- java - 如何远程执行测试代码(maven/java/testNG/selenium)?
- java - Tomcat - JRE_HOME 环境未正确定义 - Java 11
- php - Composer 错误:您的要求无法解析为一组可安装的软件包
- flutter - 列表
到地图 在 Dart 到 Firestore - python - 将 YUV_NV12 转换为 YUV444
- http-live-streaming - Exoplayer 播放时边缘粗糙