0

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?

Andrew Krasny
  • 71
  • 2
  • 4
  • Is there a question in here? It looks to me like you had a problem, fixed it, and are providing the answer here -- which is commendable!! -- but you should break this up into the original problem as the question, and then answer it yourself (and accept your own answer). That will make it clearer to everybody what happened here. – dcsohl May 28 '15 at 17:53
  • Ah, thanks, dcsohl. I'll try to do this ;) – Andrew Krasny May 28 '15 at 18:44

2 Answers2

1

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
Andrew Krasny
  • 71
  • 2
  • 4
  • There is no need to configure the Surefire plugin to use "-javaagent", *provided* you run tests on a *developer* JRE (ie, from a JDK installation) rather than a *customer* JRE (ie, a standalone JRE). – Rogério May 28 '15 at 19:12
  • You also will have to put the jmockit dependency before the junit dependency, as I recall. Or is this no longer the case? – dcsohl May 28 '15 at 19:59
  • Yes, I've seen this in some posts (that the jmockit dependency must be before the junit dependency), but for me it work either way. – Andrew Krasny May 28 '15 at 20:30
  • Rogério, could you, please, give an example of how to pass -javaagent w/o the maven-surefire-plugin? Thanks! – Andrew Krasny May 28 '15 at 20:33
  • @Rogério comment is outdated. The official documentation says to add the Java agent: https://jmockit.github.io/tutorial/Introduction.html#maven – cbaldan Feb 05 '20 at 20:02
0

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>
pamcevoy
  • 1,136
  • 11
  • 15