Reputation: 849
I need to use PowerMockito to test if a specific static method is called. I am using the following PowerMockito and JUnit libraries ...
I am having issues getting the PowerMockito.verifyStatic() method to work properly. In the following code example, I have tried using the @PrepareForTest, and mockStatic(), and I have tried excluding them. In the code example I include them.
Test Class:
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(PowerMockRunner.class)
@PrepareForTest(Test1.class)
public class PowerMockTest {
@Test
public void staticVerifyTest() {
PowerMockito.mockStatic(Test1.class);
// Test
PowerMockito.verifyStatic();
//Test1.staticMethod();
}
}
Class Under Test:
public class Test1 {
public static void staticMethod() {
System.out.println("Static Method!");
}
}
The test passes when it is run, but it should fail because Test1.staticMethod() is never called. Any help on this would be greatly appreciated!
Upvotes: 15
Views: 51415
Reputation: 14971
Using powermock-api-mockito2
and powermock-module-junit4
version 2.0.7 and either Mockito 2.28.2 or 3.3.3, with a test defined like the below, I kept getting an error about "TooManyActualInvocations: Wanted 1 time but was 2 times."
public class StaticClass {
// Note: void method with arguments
public static void doSomething(final String arg) {
doSomethingElseWithArg(arg);
}
}
public class ClassUnderTest {
public void doWork(String arg) {
StaticClass.doSomething(arg);
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(StaticClass.class)
public class MyTest {
ClassUnderTest tester = new ClassUnderTest();
@Test
public void myStaticTest() throws Exception {
PowerMockito.mockStatic(StaticClass.class);
StaticClass.doSomething("hello"); // won't work
tester.doWork("hello");
PowerMockito.verifyStatic(StaticClass.class);
StaticClass.doSomething("hello"); // TooManyActualInvocations
}
}
After doublechecking that the original code was not calling the method twice, much doc reading and many bunny trails, I finally got it to work. The test method needed to look like this instead:
@Test
public void myStaticTest() throws Exception {
PowerMockito.mockStatic(StaticClass.class);
PowerMockito.doNothing().when(StaticClass.class, "doSomething", "hello");
tester.doWork("hello");
PowerMockito.verifyStatic(StaticClass.class);
// specify the method and the args expected in the call
StaticClass.doSomething("hello");
}
It took me so long to figure this out I'm documenting for the next person.
Upvotes: 1
Reputation: 101
It's not an answer in itself but A) a confirmation that Oliver's comment about the method change is still valid at PowerMock 2.0.2 and B) a note with additional information on how it works.
PowerMockito.verifyStatic() calls Mockito.verify() which has a few examples at its Javadoc:
verify(mock, times(5)).someMethod("was called five times");
verify(mock, atLeast(2)).someMethod("was called at least two times");
As this sintax is not available anymore we need 2 lines of code to declare the validation rule. Using John's example this means that the first 3 lines would be "actual" business calls and the one after verifyStatic is just telling it which call counter must match the 2nd parameter:
PowerMockito.mockStatic(Test1.class);
// Test
Test1.staticMethod();
Test1.staticMethod();
Test1.staticMethod();
// Validation
PowerMockito.verifyStatic(Test1.class, Mockito.times(3));
Test1.staticMethod();
Upvotes: 10
Reputation: 116
For me, I encountered this issue when upgrading to powermock 2.0.0-beta.5
from 1.7.0
and so these solutions posted above DID NOT help solve my problem. Instead, I had to add the mocked class inside of the verify static call as posted within the documentation for powermock (https://static.javadoc.io/org.powermock/powermock-api-mockito/1.7.1/deprecated-list.html)
So I went from:
PowerMockito.verifyStatic(Mockito.times(1));
to:
PowerMockito.verifyStatic(Test1.class, Mockito.times(1));
This solved my problem when using the libraries below:
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.18.0'
testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '2.0.0-beta.5'
testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '2.0.0-beta.5'
Upvotes: 8
Reputation: 849
Alright, I figured it out thanks to Stefan Birkner's reference
Here is the correction to my sample code:
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(PowerMockRunner.class)
@PrepareForTest(Test1.class)
public class PowerMockTest {
@Test
public void staticVerifyTest() {
PowerMockito.mockStatic(Test1.class);
// Test
Test1.staticMethod();
PowerMockito.verifyStatic();
Test1.staticMethod();
}
}
After the static method is invoked, you need to verify that it was called by calling it again after your verifyStatic() call.
i.e.
Test1.staticMethod();
PowerMockito.verifyStatic();
Test1.staticMethod();
You can also check if it was called multiple times like this...
Test1.staticMethod();
Test1.staticMethod();
Test1.staticMethod();
PowerMockito.verifyStatic(Mockito.times(3));
Test1.staticMethod();
Upvotes: 28