验证对静态方法的调用

Hug*_*sse 5 java junit mockito powermockito

我想验证一个public static void方法被称为.

@RunWith(PowerMockRunner.class)
@PrepareForTest({ConsoleLog.class})
public class AdContentDataUnitTest {

    @Before
    public void setUp() throws Exception {
        PowerMockito.mockStatic(ConsoleLog.class);
    }

    @Test
    public void adContentData_sendTrackingEvent_noUrl() throws Exception {
        mAdContentData = spy(mAdContentData);

        // PowerMockito.doNothing().when(ConsoleLog.class);

        verifyStatic();
        mAdContentData.sendTrackingEvent("event1");
        //verifyStatic();
    }
}
Run Code Online (Sandbox Code Playgroud)

sendTrackingEvent将被调用,ConsoleLog.v(String, String)并将被调用.我可以在调试中看到调用静态方法,但出现以下日志并且测试失败:

Wanted but not invoked com.example.logger.ConsoleLog.v(
    "AdContentData",
    "sendTrackingEvent: event event1 does not exist."
);
Run Code Online (Sandbox Code Playgroud)

我试图添加verifyStaticafter但相同的日志,如果我删除第一个验证,则不会检查任何内容.如果我模拟整个ConsoleLog类,则会Unfinished stubbing detected here: [...] PowerMockitoCore.doAnswer出现错误.

有谁知道如何正确地做到这一点?

Sto*_*ica 3

有谁知道如何正确地做到这一点?

是的。根本不要这样做。

假设您有一个调用静态方法的类,如下所示:

class Person {
    private final int id;

    Person() {
        id = IdGenerator.gen();
    }
}
Run Code Online (Sandbox Code Playgroud)

将静态调用提取到非静态方法:

class Person {
    private final int id;

    Person() {
        id = generateId();
    }

    protected int generateId() {
        return IdGenerator.gen();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以编写一个测试,覆盖提取的方法:

    final int id = 1;
    Person person = new Person() {
        @Override
        protected int generateId() {
            return id;
        }
    };

    // test with person, knowing we control id
Run Code Online (Sandbox Code Playgroud)

但理想的解决方案实际上是重构被测代码,根本不使用此类静态调用,而是使用依赖注入。