Emma code coverage with JUnit and Powermock - junit

I am using JUnit with Powermockito mocking.
I have to work on a CLI environment with maven or ant.
emma version: ema-2.0.5312
powermock version: powermock-mockito-1.5.1-full
junit version: junit-4.9
When I run junit through the following command, everything works find:
java org.junit.runner.JUnitCore some.package.ClassTest
However, when I used emma to check the code coverage:
java emmarun -cp $CLASSPATH -report txt org.junit.runner.JUnitCore some.package.ClassTest
I got the following error:
1) initializationError(some.pakage.ClassTest)
java.lang.ClassCastException: org.powermock.modules.junit4.PowerMockRunner cannot be cast to org.junit.runner.Runner
Other test classes without using powermock work fine.
Does anyone have some suggestion to this? thanks in advance.

while using powermock, you can not find out the coverage using Emma
See this discussion on developer's side

You can use MockitoJunitRunner and specify a rule to use PowerMock since Eclemma works along with MockitoJUnitRunner.
Something like this:
#RunWith(MockitoJUnitRunner.class) // This supports Eclemma Plugin. Powermock doesn't.
#PrepareForTest({/* StaticClasses for Powermock here */})
public class ClassTest {
// These two statements; the static block and #Rule make sure Powermock works along with Mockito!!
static {
PowerMockAgent.initializeIfNeeded();
}
#Rule
public PowerMockRule powerMockRule = new PowerMockRule();
#Mock // To mock dependent class
private MockClass mock;
#InjectMocks //To Inject all mocks in this class
private ClassUnderTest classObject;
//Rest of the code here.
}
Dependencies needed:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4-rule-agent</artifactId>
<version>1.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency
Also you need to add this to the configurations under Coverage As -> Coverage Configurations -> Arguments.
Inside VM Arguments add -noverify and save.
for this to work with Jacoco use the following statement in your pom.xml .
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<argLine>${argLine} -noverify -javaagent:${settings.localRepository}/org/powermock/powermock-module-javaagent/1.6.2/powermock-module-javaagent-1.6.2.jar</argLine>
</configuration>
</plugin>

Related

How to import the '#Test' method in Java

I am trying to use the #Test function on a small program as I am directed to using Java 8 tutorial on youtube. Find it here.
I am up to lesson 2 which starts at 21:59.
Here is the youtube link.
https://www.youtube.com/watch?v=grEKMHGYyns
However, I have the following errors:
When trying to import the Test function the advice given by my Apache Netbeans IDE is ...
"package org.junit does not exist"
... the same happens for "org.Assert"
Over the "#Test" function on line 9 of my PersonTest.java file, the IDE gives the error...
"Cannot find symbol".
The same error exists over the "assertEquals" method on line 13.
Attempted Solution 1: Search dependency at Maven Repositories for org.junit.Test.
Result 1: "No matching items."
Attempted Solution 2: write the dependencies into the pom.xml file.
Result: n/a. Nothing happened.
My code on the PersonTest.java file:
package com.marcusbiel.javacourse.lesson2;
import org.junit.Test;
import org.Assert.assertEquals;
public class PersonTest {
#Test
public void shouldReturnHelloWorld() {
Person tristan = new Person();
assertEquals("Hello World",tristan.helloWorld() );
}
}
My code on the Person.java file:
package com.marcusbiel.javacourse.lesson2;
public class Person {
public String helloWorld(){
return "Hello World";
}
}
My code on the pom.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>mavenproject1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>12</maven.compiler.source>
<maven.compiler.target>12</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Note: I tried to fix the problem by adding in the...
"
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
... part. I don't think it's working. I have no feedback from the program on that note.
When I run it. I want to see a messaging saying "all tests passed". As in the video here... (I have a timestamp on this link where the outcome occurs).
youtu.be/grEKMHGYyns?t=2125
Problem is very old JUnit version 3.8.1 (from 2007) combined with code that requires JUnit 4.
Issue can be solved by using Junit 4:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
Also Assert.assertEquals import is wrong. Should be:
import static org.junit.Assert.assertEquals;
I think that you should clean up and update your project dependencies.
Perform a mvn clean install from netbeans IDE.
This will update your project dependencies. I think this will solve the issue of unresolvable dependencies.
Here is the doc to using maven with netbeans

Liferay 7 & JUnit : Mock Local Custom Local Service Util

I'm trying to mock with powermockito my custom local service util, but i always get an error.
#RunWith(PowerMockRunner.class)
#PrepareForTest({ServiceSubscriptionLocalServiceUtil.class})
public class CStreamTest {
#Before
public void setUp() throws NoSuchFieldException, IllegalAccessException {
.........
mockStatic(ServiceSubscriptionLocalServiceUtil.class);
.........
}
}
and i'm getting the following error :
java.lang.ExceptionInInitializerError
at sun.reflect.GeneratedSerializationConstructorAccessor4.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:48)
at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
at org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:19)
at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMock(SubclassByteBuddyMockMaker.java:47)
at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createMock(ByteBuddyMockMaker.java:25)
at org.powermock.api.mockito.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:41)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:35)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:62)
at org.mockito.Mockito.mock(Mockito.java:1896)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMethodInvocationControl(DefaultMockCreator.java:108)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.doCreateMock(DefaultMockCreator.java:61)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMock(DefaultMockCreator.java:53)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.mock(DefaultMockCreator.java:40)
at org.powermock.api.mockito.PowerMockito.mockStatic(PowerMockito.java:62)
at com.e.c.stream.impl.test.CStreamTest.setUp(CStreamTest.java:50)
i add some parts of my pom.xml :
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.24.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
Any ideas ?
Thanks
Liferay's *LocalServiceUtil classes contain a bunch of static methods that just simplify the lookup of an actual service implementation. Given that you state you're on Liferay 7, you should just utilize the services themselves and rely on #Reference dependency management and injection in the code that uses them. This way you just need to mock a regular interface that is not loaded with some default implementation and lookup.
Another option is to test the implementation - and write tests for the code "above" the service, as well as its implementation. It's typically hard to write UI-layer code, e.g. portlets, in a test-driven fashion, where mocking isn't heavily dependent on the implementation of the service and the calling classes.
Normally services utility classes created by Service builder do not have a no arg constructor, not even a constructor for that matter.
But if you check the log you will see and this is your issue:
New instance of the class is created inside PowerMock.
java.lang.ExceptionInInitializerError at sun.reflect.GeneratedSerializationConstructorAccessor4.newInstance(Unknown Source)
After trying to create an instance for: ObjenesisBase....
Even though it has not constructors, services utils normally initialize static members, like a ServiceTracker.
You could create a bummy service impl or your code could use the service reference instead of the util, you could mock that guy. Several options here, even mocking methods that give you the service to give you a dummy service.
But in summary, you cannot just do:
mockStatic(ServiceSubscriptionLocalServiceUtil.class);
As this will create an instance, and that instance has static members that need to be initialized.

Migration issue from Junit 4 to Junit 5

I am migrating my codebase from junit4 to junit5.I have used mockito in my testcase.Below are the different version that i am using for the dependency.
<junit.jupiter.version>5.2.0</junit.jupiter.version>
<junit.platform.version>1.2.0</junit.platform.version>
<org.mockito.version>1.10.19</org.mockito.version>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.19.0</version>
<scope>test</scope>
</dependency>
I have used the annotation #RunWith(MockitoJUnitRunner.class) to run my mockito code.Replaced the same with #ExtendWith(MockitoExtension.class)
But when i run the test case i get the below error. Any suggestion to solve this issue. I suspect is there any dependency version issue which is causing this problem.
java.lang.NoClassDefFoundError: org/mockito/quality/Strictness
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
at java.lang.Class.getConstructor0(Class.java:3075)
at java.lang.Class.getDeclaredConstructor(Class.java:2178)
at..
Thanks
-Sam
The JUnit5 MockitoExtension uses org.mockito.quality.Strictness so in order to use MockitoExtension you'll need to use a version of mockito-core which contains org.mockito.quality.Strictness. mockito-core:1.10.19 does not contain that class because that class was added in Mockito 2.x. So, in order to use MockitoExtension you'll need to use at least version 2.x of mockito-core.
The Mockito docs don't make this explicit but I suspect the expectation is that you'll use the same Mockito version for mockito-core and for mockito-junit-jupiter.
The following dependencies will allow you to use the JUnit5 MockitoExtension successfully:
<org.mockito.version>2.19.0</org.mockito.version>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${org.mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${org.mockito.version}</version>
<scope>test</scope>
</dependency>
I tried to use same version for mockito-junit-jupiter and mockito-core, but fails.
At last I init the mocks myself in #BeforeEach block.
#BeforeEach
private void setup() {
MockitoAnnotations.initMocks(this);
}
as a workaround.
Thanks for the response #glytching .With your input i was able to find the correct version dependency for me and it resolved my issue. Below is the version that i used to resolve the same.
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>1.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.22.0</version>
<scope>test</scope>
</dependency>
Also i needed mockito-core => version 2.22.0. But above mentioned mockito-junit-jupiter comes with mockito core dependency internally.So no need to add that dependency.

Which dependencies do I need to use Mockito and JUnit in an Eclipse RCP Tycho project

This is my current test fragment:
<packaging>eclipse-test-plugin</packaging>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>com.springsource.org.junit</artifactId>
<version>4.7.0</version>
</dependency>
</dependencies>
with the following plugins configuration:
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<version>${tycho.version}</version>
<configuration>
<dependencies>
<dependency>
<type>p2-installable-unit</type>
<artifactId>org.eclipse.equinox.ds</artifactId>
</dependency>
<dependency>
<type>p2-installable-unit</type>
<artifactId>org.apache.felix.gogo.shell</artifactId>
</dependency>
</dependencies>
<providerHint>junit47</providerHint>
<argLine>-ea</argLine>
</configuration>
</plugin>
and I use the POM-first approach to resolve dependencies:
<pomDependencies>consider</pomDependencies>
The above JUnit Version is the only one I could find, that is packaged as a bundle.
The problem is that I cannot find a match which allows me to use JUnit and Mockito together in a fragment.
My common issues are:
Mockito-core from Maven Central needs Hamcrest 1.0-2.0, but the JUnit bundle exports Hamcrest in version 4.7.0
There is no junit-dep bundle available in the Springsource repository
When I add another Hamcrest bundle, I have version conflicts between the versions exported by JUnit (4.7.0) and the Hamcrest bundle (1.3)
I would like to avoid creating my own bundle from JUnit, Hamcrest and Mockito.
I have found that the wrapper bundles of JUnit, Hamcrest, and Mockito from the Eclipse Orbit work well together.
For the (currently) latest Orbit release, which includes JUnit 4.11, Hamcrest 1.1 (with Hamcrest Core in version 1.3), and Mockito 1.8.4, just add the following snippet to your POM:
<repositories>
<repository>
<id>orbit-kepler</id>
<url>http://download.eclipse.org/tools/orbit/downloads/drops/R20130517111416/repository/</url>
<layout>p2</layout>
</repository>
</repositories>
In the wrappers of the Eclipse Orbit, the org.junit bundle exports parts of the package org.hamcrest.core. Mockito however needs the complete content of the org.hamcrest.core package. In order to prevent accidental wiring between the Mockito and JUnit bundle, the export is marked with a mandatory attribute. Unfortunately, p2 doesn't take these into account (and Tycho uses p2 for dependency resolution), so you need to give the dependency resolution of your fragment (using Mockito) an extra hint:
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>target-platform-configuration</artifactId>
<version>${tycho-version}</version>
<configuration>
<dependency-resolution>
<extraRequirements>
<requirement>
<type>eclipse-plugin</type>
<id>org.hamcrest</id>
<versionRange>0.0.0</versionRange>
</requirement>
</extraRequirements>
</dependency-resolution>
</configuration>
</plugin>
This makes sure that the org.hamcrest bundle is used during dependency resolution, and that Mokito's imports can be wired successfully.

jetty-env.xml with DataSource leads to failing WebAppContext on mvn jetty:run

I have a really simple webapp project with maven and jetty that has been working very well until now. But now I need to setup MySQL connection pooling with JNDI as the database connections always time out.
First of all here is the relevant content of my pom.xml:
<modelVersion>4.0.0</modelVersion>
...
<packaging>war</packaging>
...
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jetty-version>8.1.0.v20120127</jetty-version>
</properties>
<dependencies>
...
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.20</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-version}</version>
<type>maven-plugin</type>
</dependency>
</dependencies>
...
<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-version}</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
</configuration>
</plugin>
</plugins>
...
</build>
Now I created a jetty-env.xml in the folder /src/main/webapp/WEB-INF with the following content:
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<New id="project-db" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg>jdbc/db</Arg>
<Arg>
<New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
<Set name="url">jdbc:mysql://www.example.com:3306/mydb</Set>
<Set name="username">dbuser</Set>
<Set name="password">dbpass</Set>
</New>
</Arg>
</New>
</Configure>
But the problem is that I can't even test if this connection works as the jetty-maven-plugin fails to start on the goal
mvn jetty:run
with the following error:
WARN:oejw.WebAppContext:Failed startup of context o.m.j.p.JettyWebAppContext
{/,file:/D:/documents/programmierung/workspace/battleships-trunk/src/main/webapp/}
,file:/D:/documents/programmierung/workspace/battleships-trunk/src/main/webapp/
java.lang.IllegalArgumentException: Object of class
'org.mortbay.jetty.plugin.JettyWebAppContext' is not of type
'org.eclipse.jetty.webapp.WebAppContext'.
Object Class and type Class are from different loaders.
So how can I get this to work? I'm forced to use Jetty version 8.x as I need WebSocket support and as the remote productive server will be running Jetty 8.
EDIT
Before Pavel Veller's answer I tried the following: Deployed the assembled war to the remote jetty8 server and got the same error only that the previous error now reads as follows:
java.lang.IllegalArgumentException: Object of class
'org.eclipse.jetty.webapp.WebAppContext' is not of type
'org.eclipse.jetty.webapp.WebAppContext'.
Object Class and type Class are from different loaders.
So it seems as if there are multiple class loaders conflicting.
EDIT2
As requested by Pavel I recreated the error with a simplified webapp which you can find here on Dropbox. It is a zipped eclipse maven project.
Try removing the dependency on jetty-maven-plugin- this dependency adds the plugin to the WAR, which you don't want.
If you need to use any classes from Jetty itself, add a dependency for the specific version of Jetty (rather than the plugin) with a scope of provided.
It looks like it's pulling jetty 6 from somewhere. The exception you're seeing seems to be coming from the code that parses jetty-env.xml (org.mortbay.jetty.plus.webapp.EnvConfiguration). The XMLConfiguration class compares the class you declare on the Configure element with the actual class of what it gets from getWebAappContext(). The latter is instance of org.mortbay.jetty.plugin.JettyWebAppContext in your case and you expect it to be org.eclipse.jetty.webapp.WebAppContext (which would be the parent class for JettyWebAppContext had they both come from the same "namespace").
It's hard to tell where that would be happening from but maybe inspect your .m2 and confirm you have the proper binaries for your jetty dependencies? It has got to be running not the version you expect it to run.
UPDATE. Jetty does the following when it loads the classes defined in the configuration:
first load with Thread.currentThread().getContextClassLoader() and
loop through all getParent() until all options are exhausted.
if not successful, attempt to load with the class loader that loaded
jetty core classes (XmlConfiguration.class.getClassLoader())
looping through all the parents as well.
If still not successful, do a Class.forName()
Report ClassNotFoundException if not successful.
you can see it in the code of org.mortbay.util.Loader(http://grepcode.com is a great resource for a quick look under the hood)
It does load the class in your case, but apparently not with the right class loader.
I would now assume you have an extra jetty JAR somewhere on your classpath that interferes with the order of things.
Had a same issue caused by :
<useTestClasspath>true</useTestClasspath> (true instead of false)
That put a extra jetty jar in the classpath...
Including the dependency scope solved the error for me.
<scope>provided</scope>
In the pom.xml it looks like this,
<!-- JETTY DEPENDENCIES -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>${jetty.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<version>${jetty.version}</version>
<scope>provided</scope>
</dependency>
in the jetty dependencies and the errors went off. And btw, the jetty version I'm using is 9.3.7.v20160115.
I had the same issue and fixed it but can't figure out why.
By changing
org.eclipse.jetty.webapp.WebAppContext
to
org.eclipse.jetty.maven.plugin.JettyWebAppContext
it started to work for some reason, can't figure out exactly why. Clearly maven plugin has something to do with it?