JUnit 5 does not execute method annotated with BeforeEach

JavaMavenJunit5

Java Problem Overview


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?

Java Solutions


Solution 1 - Java

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

Solution 2 - Java

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>

Solution 3 - Java

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>

Solution 4 - Java

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)

Solution 5 - Java

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>

Solution 6 - Java

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

Solution 7 - Java

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>

Solution 8 - Java

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!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDavidView Question on Stackoverflow
Solution 1 - JavaMichaelView Answer on Stackoverflow
Solution 2 - JavaSam BrannenView Answer on Stackoverflow
Solution 3 - JavaKHanusovaView Answer on Stackoverflow
Solution 4 - JavaSrikanthView Answer on Stackoverflow
Solution 5 - JavanikliView Answer on Stackoverflow
Solution 6 - JavaDisplay nameView Answer on Stackoverflow
Solution 7 - JavaOSGI JavaView Answer on Stackoverflow
Solution 8 - JavaEric RomrellView Answer on Stackoverflow