使用PowerMock和Mockito进行静态模拟无法正常工作

Pra*_*ota 5 java junit unit-testing mockito powermock

我正在尝试验证我的一个类中是否调用了Collections.shuffle()方法.我通过Mockito阅读了关于PowerMock的(小)文档,并阅读了解决这个问题的其他SO问题并没有得到解决方案.

@RunWith(PowerMockRunner.class)
@PrepareForTest(Collections.class)
public class MyTest {

    @Test
    public void testShuffle() {
        PowerMockito.mockStatic(Collections.class);
        PowerMockito.doCallRealMethod().when(Collections.class);
        Collections.shuffle(Mockito.anyListOf(Something.class));

        ClassToTest test = new ClassToTest();
        test.doSomething();

        PowerMockito.verifyStatic(); // Verify shuffle was called exactly once
        Collections.shuffle(Mockito.anyListOf(Something.class));
    }
}

public class ClassToTest {
    private final List<Something> list;
    // ...
    public void doSomething() {
        Collections.shuffle(list);
        // do more stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

鉴于上面的代码,我希望单元测试通过.但是,单元测试失败如下:

Wanted but not invoked java.util.Collections.shuffle([]);
Actually, there were zero interactions with this mock.
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

谢谢

编辑: 根据下面的建议我尝试了以下,我得到了同样的错误.

@RunWith(PowerMockRunner.class)
@PrepareForTest(Collections.class)
public class MyTest {

    @Test
    public void testShuffle() {
        PowerMockito.mockStatic(Collections.class);

        ClassToTest test = new ClassToTest();
        test.doSomething();

        PowerMockito.verifyStatic(); // Verify shuffle was called exactly once
        Collections.shuffle(Mockito.anyListOf(Something.class));
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 5

这是一个相当古老的问题,但我仍然想澄清接受的答案实际上是不正确的。通过执行以下代码,

PowerMockito.mockStatic(Collections.class);
Collections.shuffle(Mockito.anyListOf(Something.class));
Run Code Online (Sandbox Code Playgroud)

之后所有验证都将通过:

PowerMockito.verifyStatic(); // Verify shuffle was called exactly once
Collections.shuffle(Mockito.anyListOf(Something.class));
Run Code Online (Sandbox Code Playgroud)

即使您不调用test.doSomething();答案中提供的测试,它仍然会通过。测试这一点的正确方法是实际检查 List 中的项目是否已正确排序。