Issue
When using JMockit with Maven for unit tests, it is required to pass the location of jmockit.jar
to the VM by setting the -javaagent
parameter. The maven-dependency-plugin
can do this automatically, I have set up a configuration that does the expected like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${dependency.plugin.version}</version>
<executions>
<execution>
<goals>
<goal>properties</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<argLine>-javaagent:${org.jmockit:jmockit:jar}</argLine>
</configuration>
</plugin>
This works when the test suite and also single tests are called from command line, e.g. by
mvn test -Dtest=MyClass#someTest
From within NetBeans it is also possible to run the whole test suite (e.g. when "Clean and Build" is executed). But when a single file is tested, the path is not injected. There is a command like the following in the log when the VM crashes:
Command was /bin/sh -c cd /home/kap && /usr/lib/jvm/adoptopenjdk-8-hotspot-amd64/jre/bin/java '-javaagent:${org.jmockit:jmockit:jar}' -jar ...
i.e. the placeholder is not filled with the correct location. In contrast, a call on the command line produces
[DEBUG] Forking command line: /bin/sh -c cd /home/kap/ && /usr/lib/jvm/adoptopenjdk-8-hotspot-amd64/jre/bin/java -javaagent:/home/kap/.m2/repository/org/jmockit/jmockit/1.49/jmockit-1.49.jar
It is especially weird that it works with the whole test suite, but not for single tests.
Solution
Why does the single test fail?
When executing clean and build
NetBeans by default executes mvn clean install
. So the maven executes the goal org.apache.maven.plugins:maven-dependency-plugin:properties
during its normal build lifecycle and the plugin creates variable ${org.jmockit:jmockit:jar}
.
When executing single test file (i.e. Project -> TestFile -> RightClick -> Test File
(or Ctl+F6)) NetBeans executes only single goal mvn -Dtest=MyClass#someTest surefire:test
. So the maven-dependency-plugin:properties doesn't execute at all and maven could not find the variable ${org.jmockit:jmockit:jar}
because it was not been created.
How to solve it?
Option 1.
Go to Project -> Properties -> Actions
and for actions Test File set options to execute goal as follows:
test-compile org.apache.maven.plugins:maven-dependency-plugin:properties surefire:test
NetBeans creates the nbactions.xml file so the solution would work only when executing a single test from NetBeans.
Option 2.
Remove maven-dependency-plugin from you pom.xm. Instead specify the location to jmockit.jar using ${settings.localRepository}
property:
...
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<jmockit.version>1.43</jmockit.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<argLine>-javaagent:"${settings.localRepository}"/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar</argLine>
</configuration>
</plugin>
</plugins>
</build>
...
Option 3.
I would assume binding the properties goal to the test-compile phase of maven but it would only work if disabling the Compile On Save feature of NetBeans.
...
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>test-compile</phase>
<goals>
<goal>properties</goal>
</goals>
</execution>
</executions>
...
Answered By - Dmitry.M