简体   繁体   English

当调用多个静态方法时,使用 Mockito 验证静态方法调用

[英]Verify static method calls with Mockito when more than one static method is invoked

I am trying to verify that a static method is called during the test.我试图验证在测试期间调用了静态方法。 However, it throws an exception due to the fact that more than one static method of the same class is called during the run.但是,由于在运行期间调用了多个同一个类的静态方法,它会引发异常。 Both these static methods are mocked.这两个静态方法都被模拟了。 The exact exception is like this :-确切的例外是这样的:-

An unexpected error occurred while verifying a static stub.验证静态存根时发生意外错误。

To correctly verify a stub, invoke a single static method of com.booking.capacityservicejobs.models.YourStaticClass in the provided lambda.要正确验证存根,请在提供的 lambda 中调用 com.booking.capacityservicejobs.models.YourStaticClass 的单个静态方法。

For example, if a method 'sample' was defined, provide a lambda or anonymous class containing the code.例如,如果定义了方法“sample”,请提供包含代码的 lambda 或匿名类。

The code is something like this:-代码是这样的:-

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));
    }

Can I get around this limitation without using powermock?我可以在不使用 powermock 的情况下绕过这个限制吗? What is the correct way to verify multiple(different) static method calls?验证多个(不同)静态方法调用的正确方法是什么?

Even if I agree is not a good practice, I have had to deal myself with this issue because I had a dependency with a static utilities class in a library that I could not refactor it, so here goes my answer.即使我同意这不是一个好的做法,我也不得不自己处理这个问题,因为我依赖于库中的静态实用程序类,我无法重构它,所以我的答案是这样的。

My case it's not exactly as yours: I was testing a method HttpUtils.logProtocolMessages that inside made a call to 2 different static methods in LoggingApi utility class;我的情况与您的情况不完全一样:我正在测试一个方法HttpUtils.logProtocolMessages ,该方法内部调用了LoggingApi实用程序类中的 2 个不同的静态方法; both mehods returned void.两种方法都返回无效。 This worked for me:这对我有用:

@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()));
    }
}

As you can see, the 2 static methods are mocked in the same lambda, both of them instructed to return nothing.如您所见,这两个静态方法在同一个 lambda 中被模拟,它们都被指示不返回任何内容。 I would say that any case going beyond this should consider a redesign (if possible), or even the test itself.我想说,超出此范围的任何情况都应考虑重新设计(如果可能),甚至是测试本身。

This WILL ONLY work for basic verifications with verify, such as the # of times the mocked methods are invoked.这仅适用于使用 verify 的基本验证,例如调用模拟方法的次数。 If you try to do more complex checks such as capturing arguments, the limitation of invoking a single static method in the lambda will prevail, and any assertion based on captors will fail because Mockito has not been able to properly inject their values when more than one method in the same mocked static class is invoked.如果您尝试进行更复杂的检查,例如捕获参数,则 lambda 中调用单个静态方法的限制将占上风,并且任何基于捕获器的断言都将失败,因为 Mockito 在多个时无法正确注入它们的值调用同一个模拟静态类中的方法。

This is the mockito dependency I used:这是我使用的 mockito 依赖项:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>4.1.0</version>
    <scope>test</scope>
</dependency>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM