According to PowerMock docs , I have to work with PowerMockRule instead of @RunWith(PowerMockRunner.class) and get the same results.
I seem to have found a case where this is not true.
An example is shown below:
package com.test.powermockstatics; import static org.junit.Assert.assertEquals; import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; final class FinalClassWithStaticCall { public static int getIntStatic() { return 1; } } @RunWith(PowerMockRunner.class) @PrepareForTest(FinalClassWithStaticCall.class) public class TestStaticMockingWithoutPowerMockRunner { @Test public void testStaticCall() { mockStatic(FinalClassWithStaticCall.class); when(FinalClassWithStaticCall.getIntStatic()).thenReturn(2); assertEquals(FinalClassWithStaticCall.getIntStatic(), 2); } }
But when switching to such a rule:
package com.test.powermockstatics; import static org.junit.Assert.assertEquals; import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; import org.junit.Rule; import org.junit.Test; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.agent.PowerMockAgent; import org.powermock.modules.junit4.rule.PowerMockRule; final class FinalClassWithStaticCall { public static int getIntStatic() { return 1; } } @PrepareForTest(FinalClassWithStaticCall.class) public class TestStaticMockingWithoutPowerMockRunner { static { PowerMockAgent.initializeIfNeeded(); } @Rule public PowerMockRule rule = new PowerMockRule(); @Test public void testStaticCall() { mockStatic(FinalClassWithStaticCall.class); when(FinalClassWithStaticCall.getIntStatic()).thenReturn(2); assertEquals(FinalClassWithStaticCall.getIntStatic(), 2); } }
I get the following exception:
java.lang.IllegalArgumentException: cannot subclass the final class class com.test.powermockstatics.FinalClassWithStaticCall at org.mockito.cglib.proxy.Enhancer.generateClass (Enhancer.java-00-0047) in org.mockito.cglib.core.DefaultGenerator.graterator.graterator (DefaultGeneratorStrategy.java:25) at org.mockito.cglib.core.AbstractClassGenerator.create (AbstractClassGenerator.java:217) at org.mockito.cglib.proxy.Enhancer.createHelper (Enhancer.javahaps78) at org.mockito. cglib.proxy.Enhancer.createClass (Enhancer.javahaps18) in org.mockito.internal.creation.jmock.ClassImposterizer.createProxyClass (ClassImposterizer.java:110) in org.mockito.internal.creation.jmock.ClassImposterizer.imposter ClassImposterizer.java:62) in org.powermock.api.mockito.internal.mockcreation.MockCreator.createMethodInvocationControl (MockCreator.java:111) in org.powermock.api.mockito.internal.mockcreation.MockCreator.mock (MockCreator.mock 60) at org.powermock.api.mockito.P owerMockito.mockStatic (PowerMockito.java:70) in com.test.powermockstatics.TestStaticMockingWithoutPowerMockRunner.testStaticCall (TestStaticMockingWithoutPowerMockRunner.java:30) at sun.reflect.NativeMethodAccessorImplinative.plorlectlative.ethorativeflect.notative.plorlectlativeflect.notative.plorlectlative.thorativeflect.notative.plorlectlative.ethorativepl.nativemethinativefth.nativeflect.notative.plorlectlative.notative.plf.nativefunction.ltative.ethorativepl.notative.plf.nativefunction java: 57) in sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) in java.lang.reflect.Method.invoke (Method.java:606) in org.junit.runners.model.FrameworkMethod $ 1.runReflective FrameworkMethod.java:47) in org.junit.internal.runners.model.ReflectiveCallable.run (ReflectiveCallable.java:12) in org.junit.runners.model.FrameworkMethod.invokeExplosively (FrameworkMethod.java:44) in org.junit .internal.runners.statements.InvokeMethod.evaluate (InvokeMethod.java:17) at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate (PowerMockRule.java:49) at org.junit.runners.ParentRunner.runLafaf .java: 271) in org.junit.runners.BlockJUnit4ClassRunner.runChild (BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild (BlockJUnit4ClassRunner.java:50) at org.junRunner.ununrunnernernernernernernernernernernernernernernernernernernerunner tuner ) at org.junit.runners.ParentRunner $ 1.schedule (ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren (ParentRunner.java:236) at org.junit.runners.ParentRunner.access $ 000 (ParentRunner. java: 53) in org.junit.runners.ParentRunner $ 2.valuation (ParentRunner.java:229) in org.junit.runners.ParentRunner.run (ParentRunner.java.309) in org.eclipse.jdt.internal.junit4. runner.JUnit4TestReference.run (JUnit4TestReference.java:50) in org.eclipse.jdt.internal.junit.runner.TestExecution.run (TestExecution.java:38) in org.eclipse.jdt.internal.junit.runestRnernerTem runTests (RemoteTestRunner.java:467) in org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:683) in org.eclipse.jdt.internal.junit.runner.RemoteT estRunner.run (RemoteTestRunner.java//90) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main (RemoteTestRunner.java:197)
I follow the recommendations from the docs:
put the powermock-module-junit4-rule-agent agent before junit in the Classpath
Does anyone know the official word if this is a mistake in PowerMock or the desired behavior (i.e. you just can’t mock the static method in the final class using PowerMockRule )?
EDIT:
Please read the explanation in the comments in response to Gabor Liptak . I do not want to use a statically loaded agent, since it seems that a dynamically loaded agent should be able to do the job?
I know that starting an agent will statically work. (Unfortunately, this is not an option in my project.) So, does anyone know if a dynamically loaded agent crashes in PowerMock? Or a known limitation; and why?
junit mockito powermock junit-rule junit-runner
Tom tresansky
source share