Mockito - 验证是否调用了对象方法中的静态方法

Mockito - Verify that a static method inside an Object's method is called

我有这样的问题

public class ErrorLog {
     public static void increment(String exception) {
          // do something
     }
}

import ErrorLog;
public class Calculator {
     public int division(int a, int b) {
          if (b == 0) {
               ErrorLog.increment("Divide by Zero");
          } else {
               return a / b;
          }
     }
}

我想验证调用除法的次数,但是当我被零除时,以某种方式验证静态方法 ErrorLog.increment 被调用(使用确切的字符串作为参数)。

有了 Mockito spy,我可以做这样的事情来确保调用 divide 方法。

Calculator c = new Calculator();
Calculator calcSpy = spy(c);

c.division(6, 3);
c.division(1, 0);

verify(calcSpy, times(2)).division(anyInt(), anyInt());

我也很想验证这样的事情

verify(ErrorLog, times(1)).increment("Divide by Zero");

我研究了 PowerMockito verifyStatic 构造和 mockStatic,也检查了这个 但在我的例子中,在对象内部调用的方法是静态的。

你是对的 verifyStatic 没有任何方法来检查被调用的方法。

但有一个解决方法。看看这是否适合你。

模拟静态方法的方法是使用

PowerMockito.mockStatic(ErrorLog.class)

但您也可以使用其他变体

PowerMockito.mockStatic(ErrorLog.class, invocationOnMock -> {
        assertEquals("something", invocationOnMock.getArgumentAt(0, String.class));
        return null;
    });
ErrorLog.increment("something");

如果不模拟 ErrorLog class,则无法验证

你是对的。 如果您使用静态方法,您将遇到测试和依赖注入问题,这就是一个例子。

你应该把ErrorLog转换成一个Singleton,然后你可以用spy来验证它。 例如:

public class ErrorLog {         
    private static ErrorLog = new ErrorLog();

    public static ErrorLog getInstance() {
        return errorLog;
    }

    public void increment(String exception) {
    // do something
    }
}

import ErrorLog;
public class Calculator {
    public int division(int a, int b) {
        if (b == 0) {
            ErrorLog.getInstance()increment("Divide by Zero");
        } else {
            return a / b;
        }
    }
}

从这里开始,您可以使用以下代码片段来测试调用:

ErrorLog errorLog = ErrorLog.getInstance();
ErrorLog errorLogSpy = spy(errorLog);

verify(errorLogSpy , times(1)).increment(any());

感谢您的回复,它指引了我正确的方向。对我有用的是这个(我正在使用 TestNG 框架)。

package com.apple.sample.powermock;

import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;

@PrepareForTest({ErrorLog.class})
public class TestStaticMethods extends PowerMockTestCase {
    @Test
    public void testSpy() throws Exception {

        PowerMockito.mockStatic(ErrorLog.class, invocation -> {
            assertEquals("Division by Zero", invocation.getArgument(0, String.class));
                return null;
                });

        new Math().division(10, 0);
    }
}