EclEmma and Mockito do not work well together out-of-the-box. EclEmma report no coverage at all on test run with PowerMock runner. However there is a way to make it work together, using the PowerMock javaagent. To do this, don’t use the @RunWith(PowerMockRunner.class) annotation as you’re used to. Instead, use the standard JUnit Runner or your runner extending a JUnit one, and add this rule to all your test classes:
@Rule public PowerMockRule rule = new PowerMockRule();
You will also need to add the 2 following jars to your classpath, as explained here:
- powermock-module-javaagent
- powermock-module-junit4-rule-agent
You can find then on the Maven repository: here and here.
Third step is to initialize the agent, add the following lines to all your test classes, or to you runner if you have one to add it only once:
static { PowerMockAgent.initializeIfNeeded(); }
And finally last step: modify your launch configuration running your test to add the following option to the VM arguments:
-javaagent:libs/powermock-module-javaagent-1.6.0.jar
And you should be able to use the Coverage As for EclEmma and see you test coverage result!
Hi! Thanks for your post.
I’m in a project in which we’re using JSF, JUnit 4 and PowerMock to test objects like RequestContext, Faces Context, etc. (I’m very new to this last thing)
After implementing PowerMock in my unit tests, I noticed Eclemma thew 0% coverage in tests ran with the PowerMock runner, as you said. I tried using eCoberture, but it’s old and doesn’t work well.
I tried appyling your solution, but I had to do one more thing. Besides the java agent argument, I had to add “-noverify” to the VM arguments for the JUnit execution.
Now, this doesn’t worry me too much because it’s just the configuration used for testing purposes, but I’m not entirely clear on what’s going on here.
If I don’t add “-noverify”, I get errors like “java.lang.VerifyError: Expecting a stackmap frame at branch target 84”, and none of the tests run.
Can you explain this behaviour? Is this wrong or dangerous?
Thanks very much.
Just for reference, libraries included are:
– powermock-api-mockito-1.6.2.jar
– powermock-mockito-release-full-1.6.2-full.jar
– powermock-module-javaagent-1.6.2.jar
– powermock-module-junit4-1.6.2.jar
– powermock-module-junit4-rule-agent-1.6.2.jar
– mockito-all-2.0.2-beta.jar
Hi Marcelo,
In order to mock some complex behavior (static method, final field and so on…), PowerMock has to mess with the byte code at runtime. Since Java 7, and even more since Java 8, some byte code verification mechanism has been added, which explain the error. I wrote about it here. I’m not surprised you have to use the -Xverify:none option for an IBM JVM. For a Sun JVM, -XX:-UseSplitVerifier should be enough.
Regards,
Guillaume
Is it works with Spock + PowerMock as well?
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
the above piece of code is needed if you are using Annotation in your test class.
I am getting the below message instead of getting the output if i use below VM arguments in Coverage Configuration .
-ea -noverify -javaagent:powermock-module-javaagent-1.6.5.jar
I have followed this tutorial but the coverage still shows 0%.
I am using PowerMock + EasyMock
Some of the functions i use are: EasyMock.expect(), EasyMock.replay(),EasyMock.verify()
Any idea why this does not work for me?
Hi,
Thansk for sharing above infromation. Would please advice if the above chanegs will also work with Jacoco?
Doesn’t work for me, I get this in the JUnit view:
`
java.lang.VerifyError: Expecting a stackmap frame at branch target 53
Exception Details:
Location:
com/homedepot/mm/sv/adms/bl/SupplierControllerTest.$jacocoInit()[Z @4: ifnonnull
Reason:
Expected stackmap frame at this location.
Bytecode:
0x0000000: b202 6559 c700 3157 b202 6b06 bd00 0459
0x0000010: 0314 026c b802 7253 5904 1302 7353 5905
0x0000020: 1100 dfb8 0227 535a b602 7757 0332 c002
0x0000030: 7859 b302 65b0
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
at java.lang.Class.getMethod0(Class.java:3018)
at java.lang.Class.getMethod(Class.java:1784)
at org.junit.internal.builders.SuiteMethodBuilder.hasSuiteMethod(SuiteMethodBuilder.java:20)
at org.junit.internal.builders.SuiteMethodBuilder.runnerForClass(SuiteMethodBuilder.java:13)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
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)
`
@Felix Mayer – I’m receiving the same error you are; did you ever get that resolved?
It increased the execution time . What can be done to improve the same.
Thanks for this article. It save my time a lot.
Pingback: Eclipse PowerMock coverage with ECLEmma - JavaTechji
Pingback: How to mock Final classes and have code coverage - JavaTechji
Did anyone has the fix given is working ?
This works for me! You saved my life. For reference I used this versions:
Eclipse 2019-12 (4.14.0)
Eclemma 3.1.3
powermock-module-junit4-rule-agent-2.0.7.jar
powermock-module-javaagent-2.0.7.jar
Pingback: testing - Cannot get 100% code coverage for static methods inside a final class Java | ITTone