77

JUnit 5 does not invoke my method in a test class that is annotated with the @BeforeEach annotation, where I initialize some fields of the test object that are needed in the tests. When trying to access these fields inside a test method (method annotated with @Test) I obviously get a NullpointerException. So I added some output messages to the methods.

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class TestClass {
   private String s;

   public TestClass() {

   }

   @BeforeEach
   public void init() {
      System.out.println("before");
      s = "not null";
   }

   @Test
   public void test0() {
      System.out.println("testing");
      assertEquals("not null", s.toString());
   }

}

In the output of the tests when running mvn clean test I get the "testing" message from the test0() method annotated with @Test annotation, but the "before" message is not printed.

Running de.dk.spielwiese.TestClass
!!!testing!!!
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0 sec <<< FAILURE!
de.dk.spielwiese.TestClass.test0()  Time elapsed: 0 sec  <<< FAILURE!
java.lang.NullPointerException
        at de.dk.spielwiese.TestClass.test0(TestClass.java:24)

The very obvious and only reason that I can think of is that the init() method is not invoked. The documentation of @BeforeEach says

@BeforeEach is used to signal that the annotated method should be executed before each @Test, @RepeatedTest, @ParameterizedTest, @TestFactory, and @TestTemplate method in the current test class.

I also tried running the tests in eclipse and there they always pass without any errors.

I am using maven 3.5.3. I declared JUnit Jupiter 5.1.0 as dependency in 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>de.dk</groupId>
<artifactId>spielwiese</artifactId>
<version>0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Spielwiese</name>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
    <plugins>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.0.0</version>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>de.dk.spielwiese.Spielwiese</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <appendAssemblyId>false</appendAssemblyId>
                <finalName>Spielwiese</finalName>
            </configuration>
            <executions>
                <execution>
                    <id>assemble-all</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.2</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.0.2</version>
        </plugin>
    </plugins>
</build>

<dependencies>
    <dependency>
        <groupId>de.dk</groupId>
        <artifactId>util</artifactId>
        <version>0.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.1.0</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Why is my init() method not invoked?

mrkernelpanic
  • 4,268
  • 4
  • 28
  • 52
David
  • 1,672
  • 2
  • 13
  • 32

8 Answers8

244

In my case the problem was that the @Test annotation was taken from wrong import. Originally it was imported from org.junit.Test. Once I have switched it to org.junit.jupiter.api.Test the problem was resolved.

Wrong original code:

import org.junit.Test;

@BeforeEach
...some code

@Test
...some code

Correct fixed code:

import org.junit.jupiter.api.Test;

@BeforeEach
...some code

@Test
...some code
Michael
  • 2,835
  • 2
  • 9
  • 15
  • 12
    This was the actual issue in my case also. I know there can only be one accepted answer but this seems like a much quicker check than going through the whole process of enabling surefile plugin, especially if you're using gradle. If you're running into this issue and you think you're using JUnit 5, you might not actually; check your imports! – ccellist Mar 19 '20 at 21:21
  • This worked for me too. – Theo Stefou Jul 19 '23 at 13:18
56

Your init() method is not invoked because you have not instructed Maven Surefire to use the JUnit Platform Surefire Provider.

Thus, surprisingly your test is not even being run with JUnit. Instead, it is being run with Maven Surefire's support for what they call POJO Tests.

Adding the following to your pom.xml should solve the problem.

<build>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-surefire-provider</artifactId>
                    <version>1.1.0</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>
Sam Brannen
  • 29,611
  • 5
  • 104
  • 136
  • After adding that plugin it works now, thank you. I really have to learn more about the relationships between maven, JUnit and surefire. – David Mar 24 '18 at 02:19
  • 1
    You're welcome! Regarding how Surefire works, it's a bit complicated: it will configure providers for JUnit 4 or TestNG by default, just by having them declared as dependencies in the POM. However, since JUnit 5 is not _yet_ supported out of the box by Surefire, you have to explicitly declare the `junit-platform-surefire-provider`. – Sam Brannen Mar 24 '18 at 14:41
  • 8
    Currently **upgrading maven surefire plugin to version 2.22.0+ is enough**. I report the warning message I received: `WARNING: The junit-platform-surefire-provider has been deprecated and is scheduled to be removed in JUnit Platform 1.4. Please use the built-in support in Maven Surefire >= 2.22.0 instead.` – xonya Jun 05 '20 at 12:36
  • Seconding @xonya, see also https://github.com/junit-team/junit5-samples/blob/r5.9.2/junit5-jupiter-starter-maven/pom.xml – jfrantzius Feb 16 '23 at 12:54
11

Nowadays it is not necessary to add provider to plugin. Just add junit-jupiter-engine to your dependencies (as written in official documentation https://maven.apache.org/surefire/maven-surefire-plugin/examples/junit-platform.html).

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.3.1</version>
    <scope>test</scope>
</dependency>
KHanusova
  • 187
  • 2
  • 10
10

I Faced the same issue for my gradle project. Noticed that, @Test annotation using wrong package (org.junit.Test) and the issue fixed after using correct package (org.junit.jupiter.api.Test)

Srikanth
  • 101
  • 1
  • 2
4

There is junit-jupiter-api dependency missing

<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.5.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.5.1</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.22.1</version>
    </plugin>
</plugins>
nikli
  • 2,281
  • 2
  • 24
  • 38
2

In my case the problem was that I overwrote a method annotated with @BeforeEach in a subclass of the test, so the super method was not called.

Display name
  • 2,697
  • 2
  • 31
  • 49
2

In order for Maven to execute tests properly with @BeforeEach you have to have your project correctly configured via pom.xml

Your project's pom.xml must contain these parts:

  1. dependencyManagement with Junit BOM
  2. dependency with Junit Jupiter
  3. plugin with Maven Surefire Plugin

This is documented officially here and the official project examples are here.

Here is a link to the example project's pom.xml.

Here is the example project's pom.xml for your convenience:

<?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.example</groupId>
    <artifactId>junit5-jupiter-starter-maven</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.junit</groupId>
                <artifactId>junit-bom</artifactId>
                <version>5.7.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
            </plugin>
        </plugins>
    </build>

</project>
OSGI Java
  • 545
  • 7
  • 21
0

Sam Brannen's answer worked for me, but it seems that it doesn't work with the 2.22.0 version of maven-surefire-plugin unless you upgrade the junit-platform-surefire-provider to 1.2.0. Be aware!

Eric Romrell
  • 186
  • 1
  • 4