我正在尝试验证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
}
}
给定上面的代码,我希望单元测试通过。然而,单元测试失败如下:
Wanted but not invoked java.util.Collections.shuffle([]);
Actually, there were zero interactions with this mock.
我做错了什么?
感谢
编辑:根据下面的建议,我尝试了以下操作,但我得到了相同的错误。
@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));
}
}
这是一个相当古老的问题,但我仍然想澄清的是,公认的答案实际上是不正确的。通过执行以下代码,
PowerMockito.mockStatic(Collections.class);
Collections.shuffle(Mockito.anyListOf(Something.class));
所有验证都将在之后通过:
PowerMockito.verifyStatic(); // Verify shuffle was called exactly once
Collections.shuffle(Mockito.anyListOf(Something.class));
即使你不调用test.doSomething();
,答案中提供的测试仍然会通过。正确的测试方法是实际检查列表中的项目是否正确排序。
您可以模拟/验证java.util.Collections.shuffle([])方法,也可以调用实际实现(使用PowerMockito.doCallRealMethod())。但不能同时执行这两种操作。
如果删除
PowerMockito.doCallRealMethod().when(Collections.class);
呼叫将被验证,测试将通过。
https://powermock.googlecode.com/svn/docs/powermock-1.4.7/apidocs/org/powermock/api/mockito/PowerMockito.html#doCallRealMethod%28%29
这个代码对我有效:
package test;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(Collections.class)
public class MyTest {
@Test
public void testShuffle() {
PowerMockito.mockStatic(Collections.class);
/* PowerMockito.doCallRealMethod().when(Collections.class); remove this line */
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));
}
}
class ClassToTest {
private List<Something> list = new LinkedList<Something>();
// ...
public void doSomething() {
Collections.shuffle(list);
// do more stuff
}
}
class Something {
}