JUnit 5 does not invoke my method in a test class that is annotated with the #BeforeEach annotation, where I initialize some fields of the test object that are needed in the tests. When trying to access these fields inside a test method (method annotated with #Test) I obviously get a NullpointerException. So I added some output messages to the methods.
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class TestClass {
private String s;
public TestClass() {
}
#BeforeEach
public void init() {
System.out.println("before");
s = "not null";
}
#Test
public void test0() {
System.out.println("testing");
assertEquals("not null", s.toString());
}
}
In the output of the tests when running mvn clean test I get the "testing" message from the test0() method annotated with #Test annotation, but the "before" message is not printed.
Running de.dk.spielwiese.TestClass
!!!testing!!!
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0 sec <<< FAILURE!
de.dk.spielwiese.TestClass.test0() Time elapsed: 0 sec <<< FAILURE!
java.lang.NullPointerException
at de.dk.spielwiese.TestClass.test0(TestClass.java:24)
The very obvious and only reason that I can think of is that the init() method is not invoked. The documentation of #BeforeEach says
#BeforeEach is used to signal that the annotated method should be
executed before each #Test, #RepeatedTest, #ParameterizedTest,
#TestFactory, and #TestTemplate method in the current test class.
I also tried running the tests in eclipse and there they always pass without any errors.
I am using maven 3.5.3.
I declared JUnit Jupiter 5.1.0 as dependency in my pom.xml
<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>de.dk</groupId>
<artifactId>spielwiese</artifactId>
<version>0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Spielwiese</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<archive>
<manifest>
<mainClass>de.dk.spielwiese.Spielwiese</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
<finalName>Spielwiese</finalName>
</configuration>
<executions>
<execution>
<id>assemble-all</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>de.dk</groupId>
<artifactId>util</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Why is my init() method not invoked?
In my case the problem was that the #Test annotation was taken from wrong import.
Originally it was imported from org.junit.Test.
Once I have switched it to org.junit.jupiter.api.Test the problem was resolved.
Wrong original code:
import org.junit.Test;
#BeforeEach
...some code
#Test
...some code
Correct fixed code:
import org.junit.jupiter.api.Test;
#BeforeEach
...some code
#Test
...some code
Your init() method is not invoked because you have not instructed Maven Surefire to use the JUnit Platform Surefire Provider.
Thus, surprisingly your test is not even being run with JUnit. Instead, it is being run with Maven Surefire's support for what they call POJO Tests.
Adding the following to your pom.xml should solve the problem.
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
Nowadays it is not necessary to add provider to plugin. Just add junit-jupiter-engine to your dependencies (as written in official documentation https://maven.apache.org/surefire/maven-surefire-plugin/examples/junit-platform.html).
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
I Faced the same issue for my gradle project.
Noticed that, #Test annotation using wrong package (org.junit.Test) and the issue fixed after using correct package (org.junit.jupiter.api.Test)
There is junit-jupiter-api dependency missing
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
</plugins>
In my case the problem was that I overwrote a method annotated with #BeforeEach in a subclass of the test, so the super methode was not called.
In order for Maven to execute tests properly with #BeforeEach you have to have your project correctly configured via pom.xml
Your project's pom.xml must contain these parts:
dependencyManagement with Junit BOM
dependency with Junit Jupiter
plugin with Maven Surefire Plugin
This is documented officially here and the official project examples are here.
Here is a link to the example project's pom.xml.
Here is the example project's pom.xml for your convenience:
<?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.example</groupId>
<artifactId>junit5-jupiter-starter-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.7.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
</project>
Sam Brannen's answer worked for me, but it seems that it doesn't work with the 2.22.0 version of maven-surefire-plugin unless you upgrade the junit-platform-surefire-provider to 1.2.0. Be aware!
Related
I am doing junit testing for my project that involves javafx and I encountered this issue:
Exception in thread "main" java.lang.IllegalAccessError: class org.junit.platform.engine.UniqueId (in unnamed module #0x67424e82) cannot access class org.junit.platform.commons.util.Preconditions (in module org.junit.platform.commons) because module org.junit.platform.commons does not export org.junit.platform.commons.util to unnamed module #0x67424e82
at org.junit.platform.engine.UniqueId.forEngine(UniqueId.java:67)
at com.intellij.junit5.JUnit5IdeaTestRunner.<clinit>(JUnit5IdeaTestRunner.java:86)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:375)
at com.intellij.rt.junit.JUnitStarter.getAgentClass(JUnitStarter.java:244)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:225)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) Process finished with exit code 1
I keep searching up on StackOverflow and found something similar to the issue I'm having but it only deals with illegal access to main methods instead of junit testing: Two java files. Getting IllegalAccessError when running class with main method trying to access a method from the other file.
This is my 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>proj4</artifactId>
<version>1.0-SNAPSHOT</version>
<name>proj4</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.7.1</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17-ea+11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17-ea+11</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.6</version>
<executions>
<execution>
<!-- Default configuration for running with: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>com.example.proj4/application.proj4.PizzeriaApplication</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
This is my test class
package application.proj4;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import static org.junit.jupiter.api.Assertions.*;
class PizzaTest {
#Test
void price()
{
ArrayList<Topping> n1 = new ArrayList<Topping>();
Deluxe d1 = new Deluxe(Size.Small,n1);
assertEquals(12.99, d1);
} }
Java reflection is becoming more and more restricted:
Up to Java 8 all operations are allowed
Starting from Java 9 to 15 you are still able to perform the operations, but you will receive a warning
From Java 16 and onwards the operations are forbidden between modules (well, still possible with some special arguments passed to the JVM)
This is a serious problem when using libraries that rely heavily on reflection, like PowerMock that uses it to mock objects in tests.
I created this simple example that illustrates the issue.
Here is the pom.xml:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Powermock</name>
<properties>
<java.version>16</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<parameters>true</parameters>
</configuration>
</plugin>
</plugins>
</build>
</project>
With this simple test SomeTest.java:
package com.example.demo;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
class SomeTest {
#Test
void contextLoads() {
Assert.assertEquals(1, 1);
}
}
Then if we run the command mvn clean test we will get the error:
Running com.example.demo.SomeTest
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.341 sec <<< FAILURE!
initializationError(com.example.demo.SomeTest) Time elapsed: 0 sec <<< ERROR!
java.lang.RuntimeException: java.lang.reflect.InaccessibleObjectException: Unable to make protected native
java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException accessible:
module java.base does not "opens java.lang" to unnamed module #8b96fde
Strangely if we add this bit to the pom.xml, the problem goes away:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.1</version>
</parent>
Anybody that can help me with this:
How to use PowerMock in JDK 16?
Is even PowerMock supported in JDK 16?
Is this issue solved using Java modules?
Why adding Spring Boot as parent solves the problem?
You can use PowerMockito with Java 16 by using the --illegal-access=permit option in the Maven surefire plugin. You will see warnings, but it works.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<argLine>
--illegal-access=permit
</argLine>
</configuration>
</plugin>
For reference this is what I use for Mockito and PowerMockito:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.11.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
Use This plugin in POM file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.io=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/java.base=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
JUnit 5 does not invoke my method in a test class that is annotated with the #BeforeEach annotation, where I initialize some fields of the test object that are needed in the tests. When trying to access these fields inside a test method (method annotated with #Test) I obviously get a NullpointerException. So I added some output messages to the methods.
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class TestClass {
private String s;
public TestClass() {
}
#BeforeEach
public void init() {
System.out.println("before");
s = "not null";
}
#Test
public void test0() {
System.out.println("testing");
assertEquals("not null", s.toString());
}
}
In the output of the tests when running mvn clean test I get the "testing" message from the test0() method annotated with #Test annotation, but the "before" message is not printed.
Running de.dk.spielwiese.TestClass
!!!testing!!!
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0 sec <<< FAILURE!
de.dk.spielwiese.TestClass.test0() Time elapsed: 0 sec <<< FAILURE!
java.lang.NullPointerException
at de.dk.spielwiese.TestClass.test0(TestClass.java:24)
The very obvious and only reason that I can think of is that the init() method is not invoked. The documentation of #BeforeEach says
#BeforeEach is used to signal that the annotated method should be
executed before each #Test, #RepeatedTest, #ParameterizedTest,
#TestFactory, and #TestTemplate method in the current test class.
I also tried running the tests in eclipse and there they always pass without any errors.
I am using maven 3.5.3.
I declared JUnit Jupiter 5.1.0 as dependency in my pom.xml
<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>de.dk</groupId>
<artifactId>spielwiese</artifactId>
<version>0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Spielwiese</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<archive>
<manifest>
<mainClass>de.dk.spielwiese.Spielwiese</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
<finalName>Spielwiese</finalName>
</configuration>
<executions>
<execution>
<id>assemble-all</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>de.dk</groupId>
<artifactId>util</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Why is my init() method not invoked?
In my case the problem was that the #Test annotation was taken from wrong import.
Originally it was imported from org.junit.Test.
Once I have switched it to org.junit.jupiter.api.Test the problem was resolved.
Wrong original code:
import org.junit.Test;
#BeforeEach
...some code
#Test
...some code
Correct fixed code:
import org.junit.jupiter.api.Test;
#BeforeEach
...some code
#Test
...some code
Your init() method is not invoked because you have not instructed Maven Surefire to use the JUnit Platform Surefire Provider.
Thus, surprisingly your test is not even being run with JUnit. Instead, it is being run with Maven Surefire's support for what they call POJO Tests.
Adding the following to your pom.xml should solve the problem.
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
Nowadays it is not necessary to add provider to plugin. Just add junit-jupiter-engine to your dependencies (as written in official documentation https://maven.apache.org/surefire/maven-surefire-plugin/examples/junit-platform.html).
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
I Faced the same issue for my gradle project.
Noticed that, #Test annotation using wrong package (org.junit.Test) and the issue fixed after using correct package (org.junit.jupiter.api.Test)
There is junit-jupiter-api dependency missing
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
</plugins>
In my case the problem was that I overwrote a method annotated with #BeforeEach in a subclass of the test, so the super methode was not called.
In order for Maven to execute tests properly with #BeforeEach you have to have your project correctly configured via pom.xml
Your project's pom.xml must contain these parts:
dependencyManagement with Junit BOM
dependency with Junit Jupiter
plugin with Maven Surefire Plugin
This is documented officially here and the official project examples are here.
Here is a link to the example project's pom.xml.
Here is the example project's pom.xml for your convenience:
<?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.example</groupId>
<artifactId>junit5-jupiter-starter-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.7.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
</project>
Sam Brannen's answer worked for me, but it seems that it doesn't work with the 2.22.0 version of maven-surefire-plugin unless you upgrade the junit-platform-surefire-provider to 1.2.0. Be aware!
Today I've spent some non-zero time trying to setup a simplest maven project that will run a simplest jmockit test.
While trying to write such an xml, I've faced with several problems, starting with
java.lang.NoClassDefFoundError: org.junit.runner.Runner
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:61)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
....
and later having problems with running it.
Unfortunately attempts to find quick answer using google didn't help.
So, what it the smallest pom.xml for using jmockit framework with maven?
At the end I came up with a working pom.xml which I want to share - probably this will be useful for someone.
$ cat pom.xml
<?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>jmockit-test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>1.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<argLine>-javaagent:"${settings.localRepository}"/org/jmockit/jmockit/1.17/jmockit-1.17.jar</argLine>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
</project>
And source files are:
$ cat src/main/java/com/test/jmock/DataProvider.java
package com.test.jmock;
public interface DataProvider {
Integer getInt();
Boolean getBoolean();
}
and
$ cat src/test/java/com/test/jmock/TrivialTest.java
package com.test.jmock;
import mockit.Mocked;
import mockit.NonStrictExpectations;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public final class TrivialTest {
#Mocked
private DataProvider provider;
#Test
public void test() {
init();
Integer mockIntData = provider.getInt();
System.out.println("Mock int data is " + mockIntData);
assertEquals("Unexpected result", mockIntData, Integer.valueOf(12345));
Boolean mockBoolData = provider.getBoolean();
System.out.println("Mock bool data is " + mockBoolData);
assertEquals("Unexpected result", mockBoolData, Boolean.TRUE);
}
private void init() {
new NonStrictExpectations() {
{
provider.getInt();
result = 12345;
provider.getBoolean();
result = Boolean.TRUE;
}
};
}
}
Now this works as expected!
$ mvn test
...
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.025 sec - in com.test.jmock.TrivialTest
I had the same problem. I used the answer from #andrew-krasny and modified it to use the other solution (-Djdk.attach.allowAttachSelf) so you don't have to update it when you update jmockit.
<build>
<plugins>
<!-- Compiler -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>10</source> <!-- was 1.8 -->
<target>10</target> <!-- was 1.8 -->
</configuration>
</plugin>
<!-- FIX START -->
<!-- Test -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<argLine>-Djdk.attach.allowAttachSelf</argLine>
</configuration>
</plugin>
<!-- FIX END -->
</plugins>
</build>
i am using maven failsafe plugin to execute the integration test cases along with cobertura plugin.
in the configuration of failsafe plugin, i have given suiteXmlFile which has all the integration tests
however, when run the following command , i am getting error
command is : mvn cobertura:cobertura-integration -DskipITs=false
and error is :
Failed to execute goal maven-failsafe-plugin:2.17:integration-test (failsafe-integration-tests) on project xx: suiteXmlFiles is configured, but there is no TestNG dependency
here is the snippet from pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>/home/adam/coberturaint/reporting/src/test/resources/testng/it-test.xml</suiteXmlFile>
</suiteXmlFiles>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.8</version>
</dependency>
</dependencies>
</dependencyManagement>
</configuration>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.8</version>
</dependency>
</dependencies>
</plugin>
i am using fail-safe plugin version : 2.17
i have mentioned the dependency of testng everywhere, but still i am getting dependency error
please suggest
regards
You need to go a different way cause the messages it already.
<?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>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.8</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>/home/adam/coberturaint/reporting/src/test/resources/testng/it-test.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Apart from that you need to call maven like this:
mvn verify
to run the integration-test phase. If you call Maven like this:
mvn cobertura:cobertura-integration
You have no life cycle which will not run the integration tests.
You should prevent using absolute paths in your pom file as you do with your suite file. The question is on the other hand why you need a suite file. In TestNG usually you don't need one.