如何在静态方法上使用MockedStatic验证?

发布于 2025-01-13 00:11:48 字数 1865 浏览 2 评论 0原文

我有以下 2 个不同静态方法的模拟;在我的服务方法中调用的 UnitConversion.isCompatible()Logging.error()

这是我的测试方法:

myService.demoMethod();


try (MockedStatic<UnitConversion> unitConversion= mockStatic(UnitConversion.class)) {
    unitConversion.verify(never(), () -> UnitConversion.isCompatible(any()));
    UnitConversion.isUnitsCompatible(any());
}


try (MockedStatic<Logging> logging = mockStatic(Logging.class)) {
    logging.verify(times(1), () -> Logging.error(any()));
    Logging.error(any();
}

第一个方法从未被调用,而第二个方法在我调试时被调用一次。没问题,但测试给出了第二种方法的“想要但未调用”错误。我不确定是否应该在 try 块中调用静态方法,因为我已经调用了调用静态方法的服务方法。

那么,如何使用 MockedStatic (而不是 powermock 等)验证静态方法调用?我应该在 try 块中调用它们吗?

更新:我使用以下方法,但即使从服务方法调用的静态方法断点命中一次,它仍然会给出“想要但未调用”错误。

// I also try to call the service method under the test here again
demoService.create(request);        

try (MockedStatic<LoggingUtils> mock = mockStatic(LoggingUtils.class)) {
    // as the static method is void, no need to stub and not use "when()" in here

    // I call the service method under the test
    demoService.create(request);

    // verify that the method is being invoked
    mock.verify(times(1), () -> LoggingUtils.error(any(), any()));
}

更新-II:

demoService:

public CommandDTO create(final PurchaseRequest request) {
    // code omitted

    addLog();
    return CommandDTO.builder().uuid(purchase.getUuid()).build();
}

private void addLog() {
    LoggingUtils.error("error", null);
}

LoggingUtils:

public class LoggingUtils {

    public static void error(String var1, Throwable var2) {
        log.error(getString(var1), var2);
    }
}

I have the following mocks for 2 different static method; UnitConversion.isCompatible() and Logging.error() that are called in my service method.

Here is my test method:

myService.demoMethod();


try (MockedStatic<UnitConversion> unitConversion= mockStatic(UnitConversion.class)) {
    unitConversion.verify(never(), () -> UnitConversion.isCompatible(any()));
    UnitConversion.isUnitsCompatible(any());
}


try (MockedStatic<Logging> logging = mockStatic(Logging.class)) {
    logging.verify(times(1), () -> Logging.error(any()));
    Logging.error(any();
}

The first method is never called while the second one is called one time when I debug. It is ok, but the test gives "Wanted but not invoked" error for the second method. I am not sure if I should call the static methods in try blocks, because I already call my service method that calls the static methods.

So, how can I verify the static method calls using MockedStatic (not powermock, etc)? SHould I call them in try blocks?

Update: I use the following approach, but it still gives "Wanted but not invoked" error even if breakpoint hit once to the static method called from the service method.

// I also try to call the service method under the test here again
demoService.create(request);        

try (MockedStatic<LoggingUtils> mock = mockStatic(LoggingUtils.class)) {
    // as the static method is void, no need to stub and not use "when()" in here

    // I call the service method under the test
    demoService.create(request);

    // verify that the method is being invoked
    mock.verify(times(1), () -> LoggingUtils.error(any(), any()));
}

Update-II:

demoService:

public CommandDTO create(final PurchaseRequest request) {
    // code omitted

    addLog();
    return CommandDTO.builder().uuid(purchase.getUuid()).build();
}

private void addLog() {
    LoggingUtils.error("error", null);
}

LoggingUtils:

public class LoggingUtils {

    public static void error(String var1, Throwable var2) {
        log.error(getString(var1), var2);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伤感在游骋 2025-01-20 00:11:48

我可以在这段代码中看到一些问题:

try (MockedStatic<UnitConversion> unitConversionMockStatic = mockStatic(UnitConversion.class)) {
    unitConversionMockStatic.verify(never(), () -> UnitConversion.isCompatible(any()));
    UnitConversion.isUnitsCompatible(any());
}
  • 您在调用该方法之前验证该方法是否被调用
  • ,因为您指定了您期望 never(),这会传递
  • 您使用参数匹配器调用该方法。这是非法的 - 您需要使用正常参数进行调用。

因此,测试的结构应该

try (MockedStatic<UnitConversion> unitConversionMockStatic = mockStatic(UnitConversion.class)) {
    // if needed, stub the static method with when

    // call the static method (probably indirectly, via service under thest)
    UnitConversion.isUnitsCompatible(10);

    // verify that the method is being invoked
    unitConversionMockStatic.verify(times(1), () -> UnitConversion.isCompatible(any()));
}

注意 try-with-resources 的使用,MockStatic 在关闭时不再有效(当您退出 try-with-resources 块时会发生这种情况)。因此,您必须在 try-with-resources 块内调用被测方法(调用静态方法)。

I can see a few issues in this snippet:

try (MockedStatic<UnitConversion> unitConversionMockStatic = mockStatic(UnitConversion.class)) {
    unitConversionMockStatic.verify(never(), () -> UnitConversion.isCompatible(any()));
    UnitConversion.isUnitsCompatible(any());
}
  • you verify that the method is being called before calling it
  • as you specified that you expect never(), this passes
  • you call the method with the argument matcher. This is illegal - you need to call with normal parameter.

Thus, the structure of the test should be

try (MockedStatic<UnitConversion> unitConversionMockStatic = mockStatic(UnitConversion.class)) {
    // if needed, stub the static method with when

    // call the static method (probably indirectly, via service under thest)
    UnitConversion.isUnitsCompatible(10);

    // verify that the method is being invoked
    unitConversionMockStatic.verify(times(1), () -> UnitConversion.isCompatible(any()));
}

Note the usage of try-with-resources, MockStatic is no longer in effect when it is closed (which happens when you exit from the try-with-resources block). Thus, you must invoke the method under test (which calls the static method) inside of the try-with-resources block.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文