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?
@BeforeEach is used to signal that the annotated method should be executed before each @Test method in the current test class.
@AfterAll is used to signal that the annotated method should be executed after all tests in the current test class. @AfterEach is used to signal that the annotated method should be executed after each @Test method in the current test class.
Setup. @Before annotation in JUnit is used on a method containing Java code to run before each test case. i.e it runs before each test execution.
Explanation. Annotating a public static void method with @BeforeClass causes it to be run once before any of the test methods in the class.
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
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With