Home > Software engineering >  Mockito @Mock and @InjectMocks are null
Mockito @Mock and @InjectMocks are null

Time:01-19

I am trying to test this (anonymized) code:

import org.springframework.stereotype.Service;

import java.time.LocalDate;
import com.dummy.domain.dummy.dao.MatchDAO;

@Service
public class TeamService {

    private MatchDAO matchDAO;

    public TeamService(MatchDAO matchDAO) {
        this.matchDAO = matchDAO;
    }

    public Team get(int teamId) {
        return get(teamId, LocalDate.now());
    }

    public Team get(int teamId, LocalDate date) {
        matchDAO.findMatchIdsForTeam(teamId, date);
        ...
    }
}

Using the following test code:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.time.LocalDate;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class TeamServiceTest {
    @Mock
    MatchDAO matchDAO;

    @InjectMocks
    TeamService teamService;

//    @BeforeAll
//    public void createMocks() {
//        MockitoAnnotations.initMocks(this);
//    }

    @Test
    public void testGetTeam() {
        when(matchDAO.findMatchIdsForTeam(anyInt(), any(LocalDate.class))).thenReturn(new int[]{1234, 5678});

        Team team = teamService.get(1);
        ... assertions
    }
}

But I keep getting either this error:

[ERROR] com.dummy.domain.dummy.TeamServiceTest.testGetTeam()  Time elapsed: 0 s  <<< FAILURE!
java.lang.NullPointerException: Cannot invoke "com.dummy.domain.dummy.TeamService.get(int, java.time.LocalDate)" because "this.TeamService" is null

Or this error:

[ERROR] com.dummy.domain.dummy.TeamServiceTest.testGetTeam()  Time elapsed: 0 s  <<< FAILURE!
java.lang.NullPointerException: Cannot invoke "com.dummy.domain.dummy.dao.MatchDAO.findMatchIdsForTeam(int, java.time.LocalDate)" because "this.TeamService" is null

Some tests give the error that @InjectMocks object is null and some tests give the error that the @Mock is null.

I tried it with the @BeforeAll enabled and disabled (and also as @BeforeEach). I also tried with SpringExtension instead of MockitoExtension. I have also tried many suggestions including all stated in this post: mock instance is null after mock annotation

Interestingly when running this test in maven it fails but when I try to run it in my IDE (Intellij) it is succesful. I checked and both are using the same JDK and maven version. Running it in our build pipeline is also giving the same error as local maven build.

Can anyone help with this problem?

For reference this is my 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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.dummy.domain</groupId>
    <artifactId>dummy</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Update: The xml has a parent pom with the following content: (Updated based on @khmarbaise comment)

<properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <maven-surefire-plugin.version>3.0.0-M8</maven-surefire-plugin.version>
    <junit-jupiter.version>5.9.1</junit-jupiter.version>
    <lombok.version>1.18.24</lombok.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <scope>import</scope>
            <type>pom</type>
            <version>3.0.1</version>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.10.1</version>
                <configuration>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven-surefire-plugin.version}</version>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

CodePudding user response:

In the end, I fixed the issue myself. I replaced the dependencies on junit-jupiter-api, spring-boot-test, spring-test, and mockito-junit-jupiter with a dependency on spring-boot-starter-test. Even though the starter is using the same versions I explicitly used, it did fix it.

CodePudding user response:

You need to use @BeforeEach annotation to mock the dependencies and prepare target object.

@BeforeEach
  public void setup() {
 MockitoAnnotations.initMocks(this);
}
  • Related