I am trying to mock a static non final method using PowerMock. My test class annotations look like:
@RunWith(SpringJUnit4ClassicRunner.class)
@PrepareForTest(TestClazz.class)
@ContextConfiguration(locations = {"filePath"})
My test looks something like this:
// A few mocks being defined here, for instance
// EasyMock.expect(someObject.getFirstName("First Second")).andReturn("First");
PowerMock.mockStatic(TestClazz.class);
EasyMock.expect(TestClazz.staticMethod(EasyMock.anyString())).andReturn("returnString");
PowerMock.replayAll();
object.methodCall();
PowerMock.verifyAll();
I am getting an error that says:
no last call on a mock available
java.lang.IllegalStateException: no last call on a mock available
at org.easymock.EasyMock.getControlForLastCall(EasyMock.java:559)
at org.easymock.EasyMock.expect(EasyMock.java:537)
I need the runner to be SpringJUnit4ClassicRunner as I need to load the ApplicationContext first and then mock the required classes.
I am not sure what I am missing here. Any help would be greatly appreciated. Thanks in advance.
Based on @Henri's suggestion I tried using the @PowerMockRunnerDelegate. This is the stackTrace I encounter:
InitializationError
Failed to transform class with name MyTest. Reason: java.io.IOException: invalid constant type: 18
java.lang.IllegalStateException: Failed to transform class with name MyTest. Reason: java.io.IOException: invalid constant type: 18
at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:266)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:180)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:68)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:145)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:40)
at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:244)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.<init>(JUnit4TestSuiteChunkerImpl.java:61)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.<init>(AbstractCommonPowerMockRunner.java:32)
at org.powermock.modules.junit4.PowerMockRunner.<init>(PowerMockRunner.java:34)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
Caused by: java.lang.RuntimeException: java.io.IOException: invalid constant type: 18
at javassist.CtClassType.getClassFile2(CtClassType.java:207)
at javassist.compiler.MemberResolver.lookupMethod(MemberResolver.java:110)
at javassist.compiler.MemberResolver.lookupMethod(MemberResolver.java:96)
at javassist.compiler.TypeChecker.atMethodCallCore(TypeChecker.java:704)
at javassist.expr.NewExpr$ProceedForNew.setReturnType(NewExpr.java:240)
at javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:146)
at javassist.compiler.ast.CallExpr.accept(CallExpr.java:45)
at javassist.compiler.TypeChecker.atVariableAssign(TypeChecker.java:248)
at javassist.compiler.TypeChecker.atAssignExpr(TypeChecker.java:217)
at javassist.compiler.ast.AssignExpr.accept(AssignExpr.java:38)
at javassist.compiler.CodeGen.doTypeCheck(CodeGen.java:235)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:323)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:344)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
at javassist.compiler.CodeGen.atIfStmnt(CodeGen.java:398)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:348)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
at javassist.compiler.Javac.compileStmnt(Javac.java:558)
at javassist.expr.NewExpr.replace(NewExpr.java:204)
at org.powermock.core.transformers.impl.MainMockTransformer$PowerMockExpressionEditor.edit(MainMockTransformer.java:418)
at javassist.expr.ExprEditor.loopBody(ExprEditor.java:198)
at javassist.expr.ExprEditor.doit(ExprEditor.java:90)
at javassist.CtClassType.instrument(CtClassType.java:1224)
at org.powermock.core.transformers.impl.MainMockTransformer.transform(MainMockTransformer.java:74)
at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:251)
My config has EasyMock-3.x, PowerMockEasyMock-1.6.x and PowerMockAgentJUnit4-1.6.x.
It's because you still need the
PowerMockRunner. The trick is to usePowerMockRunnerDelegate, like this