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.
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.
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.
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>
...
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>
...