Powermock: static interface method throws pending exception
I want to mock the static interface method with Powermock. Here's the interface:
public interface IConcurrentUtil {
static void threadSleep(final long millis) {
try {
Thread.sleep(millis);
} catch (final InterruptedException e) {
;
}
}
}
Here's the class that uses threadSleep:
public class ConcurrentUser {
public void callInterfaceMethod() {
IConcurrentUtil.threadSleep(3000L);
}
}
And finally, the test class:
@RunWith(PowerMockRunner.class)
@PrepareForTest(ConcurrentUser.class)
@PowerMockIgnore("javax.management.*")
public class ConcurrentUtilsTest {
private ConcurrentUser concurrentUser;
@Before
public void setUp() {
concurrentUser = new ConcurrentUser();
}
@Test
public void testThreadSleepCallsSleepCorrect() throws Exception {
mockStatic(IConcurrentUtil.class);
doNothing().when(IConcurrentUtil.class);
IConcurrentUtil.threadSleep(3000L);
concurrentUser.callInterfaceMethod();
verifyStatic(times(1));
IConcurrentUtil.threadSleep(3000L);
}
}
Powermock gives this error:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at org.powermock.api.mockito.internal.PowerMockitoCore.doAnswer(PowerMockitoCore.java:36)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
at org.powermock.api.mockito.PowerMockito.verifyStatic(PowerMockito.java:288)
at com.test.concurrent.ConcurrentUtilsTest.testThreadSleepCallsSleepCorrect(ConcurrentUtilsTest.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
I am using PowerMock 1.6.2 and JUnit 4.12.
Are there any special rules or commands that should be applied when dealing with static (or default) interface methods?
source to share
In fact, in your case, you don't need to do stubbing as mockStatic already does this for you, it's just redundant.
So the following will work:
@RunWith(PowerMockRunner.class)
@PrepareForTest(IConcurrentUtil.class)
@PowerMockIgnore("javax.management.*")
public class ConcurrentUtilTest {
private ConcurrentUser concurrentUser;
@Before
public void setUp() {
concurrentUser = new ConcurrentUser();
}
@Test
public void testThreadSleepCallsSleepCorrect() throws Exception {
PowerMockito.mockStatic(IConcurrentUtil.class);
concurrentUser.callInterfaceMethod();
PowerMockito.verifyStatic(Mockito.times(1));
IConcurrentUtil.threadSleep(3000L);
}
}
But in case you really want to take some steps, here's an example that works with the versions you are using:
PowerMockito.mockStatic(FileUtils.class, Answers.CALLS_REAL_METHODS.get());
PowerMockito.doThrow(new IOException()).when(FileUtils.class, "copyFile", any(File.class), any(File.class));
Here I am using the mockStatic 2-args signature because I want to do partial stubbing: real methods are called in the FileUtils class unless I stub it like in the second line. You can also use the 1-arg version, if you don't mind having all static methods truncated with the default answer.
You can also look at this answer and this one .
source to share