Reputation: 2181
I'm trying to verify that the Collections.shuffle() method was called in one of my classes. I read through the (little) documentation on PowerMock with Mockito and read through the other SO questions that dealt with this issue and didn't get a resolution.
@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
}
}
Given the above code, I expect the unit test pass. However, the unit test fails as follows:
Wanted but not invoked java.util.Collections.shuffle([]);
Actually, there were zero interactions with this mock.
What am I doing wrong?
Thanks
EDIT: As per the suggestion below I tried the following, and I get the same error.
@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));
}
}
Upvotes: 5
Views: 8174
Reputation: 132
This is a rather old question, but I'd still like to clarify that the accepted answer is in fact incorrect. By executing the following code,
PowerMockito.mockStatic(Collections.class);
Collections.shuffle(Mockito.anyListOf(Something.class));
all verifies will always pass afterwards:
PowerMockito.verifyStatic(); // Verify shuffle was called exactly once
Collections.shuffle(Mockito.anyListOf(Something.class));
even if you do not call test.doSomething();
the provided test in the answer will still pass. The correct way to test this is to actually check if the items in the List have been sorted correctly.
Upvotes: 5
Reputation: 777
You can either mock/verify the java.util.Collections.shuffle([]) method or call the real implementation (with PowerMockito.doCallRealMethod()). But you can't do both.
If you remove
PowerMockito.doCallRealMethod().when(Collections.class);
the call will be verified and the test will pass.
This code works for me:
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 {
}
Upvotes: 4