Search code examples
netbeansmaven-surefire-pluginjmockitjavaagentsmaven-dependency-plugin

Configure NetBeans to execute single unit tests with JMockit as javaagent


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
    

    enter image description here

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