3

Edit: I noticed that this is only a problem on JMockit 1.42 and later, so I opened an issue here

I have something similar to the following code

 class Type1 {

 }

 class Type2 {
      private final Type1 TYPE_1;

      Type2(Type1 type1) {
           TYPE_1 = type1;
      }

      // A bunch of methods involving TYPE_1
 }

I am trying to test Type2 with TestNG by mocking a Type1 instance with JMockit. I have the following test.

 class Type2Test {
      @Tested
      Type2 type2;

      @Injectable
      Type1 type1;


      @Test
      void randomTestThatShouldPass() {
           Assert.assertTrue(true);
      }
 }

However, when running this test, I get a NullPointerException with no apparent stack trace. The following is all that shown on my console.

java.lang.NullPointerException

I have tried a bunch of things to solve my problem including:

  • Making TYPE_1 non-final
  • Removing @Injectable from type1 in Type2Test. This gives me a better error message by telling me JMockit could not instantiate type2 because there are no @Injectable instances to invoke the constructor for Type2
  • Changed @Injectable to @Mocked
  • Switching environments. The same problems occur on both VSCode and Intelij
  • Using Gradle instead of Maven

The only thing that solves it is by removing all of JMockit's annotations, which is not helpful. What am I doing wrong in my test setup?

Edit: Responding to paulsm4 comment, I am not using Spring, but I am using Maven 3.5.3 with the following 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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>ok.ubc.cosc.VisualizeCode</groupId>
  <artifactId>VisualizeCode</artifactId>
  <packaging>jar</packaging>
  <version>1.0</version>
  <name>VisualizeCode</name>
  <url>http://maven.apache.org</url>
  <build>
       <plugins>
            <plugin>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <version>3.8.1</version>
                 <configuration>
                      <source>1.8</source>
                      <target>1.8</target>
                 </configuration>
            </plugin>
       </plugins>
 </build>
 <dependencies>
      <dependency>
           <groupId>org.testng</groupId>
           <artifactId>testng</artifactId>
           <version>6.14.3</version>
           <scope>test</scope>
      </dependency>
      <dependency>
           <groupId>org.jmockit</groupId>
           <artifactId>jmockit</artifactId>
           <version>1.48</version>
           <scope>test</scope>
      </dependency>
 </dependencies>
 </project>
Lindstorm
  • 890
  • 2
  • 7
  • 22
  • It sounds like a) You're probably using Spring Boot (SB 2?), and b) Your (Maven? Gradle?) config isn't bringing in the right libraries at the right time. Please update your post with the relevant "dependencies" from your build file. Also: please add your environment(e.g. "Spring Boot") to your "tags". – paulsm4 Dec 01 '19 at 21:28
  • @paulsm4 I am not using Spring Boot, but I am using Maven. I have updated the question with my pom.xml file – Lindstorm Dec 01 '19 at 21:39
  • OK: so how is "@Injectable" working? I assumed you were using Spring Boot for your "DI container". What *ARE* you using to implement DI? I'm not saying it's "wrong" ... but I *AM* curious... – paulsm4 Dec 01 '19 at 22:15
  • @paulsm4 [JMockit](http://javadox.com/org.jmockit/jmockit/1.12/mockit/Injectable.html) is the library corresponding to `@Injectable`. It tells JMockit that this instance can be injected into test code (I assume this is what you mean by a DI container). – Lindstorm Dec 01 '19 at 22:21
  • OK: I think that's the problem. Look [here](https://stackoverflow.com/a/26762680/421195): `The thing to notice about JMockit's (or any other mocking API) support for dependency injection is that it's meant to be used only when the code under test actually relies on the injection of its dependencies.` This tutorial might help: https://jmockit.github.io/tutorial/Introduction.html#mocks – paulsm4 Dec 02 '19 at 00:17
  • @paulsm4 Nothing in that link helped. From what I see, the big difference between the question asker's code and the accepted answer is that they he replaced `@Injectable` with `@Mocked` which I have already tried and stated. – Lindstorm Dec 02 '19 at 02:14
  • 2
    @paulsm4 To save you time in case you look into more, I noticed that my code (with and without the changes from the link) works with JMockit version 1.41 but none after that. – Lindstorm Dec 02 '19 at 02:28
  • Fair enough. I've re-opened and upvoted your question. In case others didn't notice your edit, you've opened an "issue" against JMockit here: https://github.com/jmockit/jmockit1/issues/639 – paulsm4 Dec 02 '19 at 03:42
  • Does `Type1` really not have any method? – Timothy Truckle Dec 02 '19 at 22:34
  • @TimothyTruckle `Type1` does have methods in my real project (as does `Type2`). I was trying to emphasize that `Type1` has a zero-argument constructor. – Lindstorm Dec 02 '19 at 23:12
  • Are you using aspectjweaver javaagent? It doesn't play well with JMockit. – seb Oct 18 '21 at 13:01

0 Answers0