JUnit 5 Tutorial - Learn How To Write Unit Tests
JUnit 5 Tutorial - Learn How To Write Unit Tests
8. Exercise: Develop unit tests for a regular expression utility method for email verification
13. Exercise: Using the @TempDir annotation to create temporary files and paths
16. Exercise: Clone the JUnit5 Github repo and review tests
18. Conclusion
This tutorial explains unit testing with JUnit with the JUnit 5 framework (JUnit Jupiter). It
explains the creation of JUnit 5 tests with the Maven and Gradle build system. It
demonstrates the usage of the Eclipse IDE for developing software tests with JUnit 5 but this
tutorial is also valid for tools like Visual Code or IntelliJ.
(https://learn.vogella.com/courses/details/java-software-testing)
1. Overview
JUnit is a popular unit-testing framework in the Java ecosystem. JUnit 5 added many new features based on
the Java 8 version of the language.
This guide gives an introduction into unit testing with the JUnit framework using JUnit 5. It focus on the usage
of the framework.
https://www.vogella.com/tutorials/JUnit/article.html 1/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
Using Maven
Company (https://www.vogella.com/company/) in the
Contact usEclipse IDE (https://www.vogella.com/tutorials/EclipseMaven/article.html)
(https://www.vogella.com/contact.html)
GET MORE...
Using the Eclipse IDE for creating and running JUnit test
Read Premium Content ...
(https://www.vogella.com/tutorials/JUnitEclipse/article.html)
(https://learn.vogella.com)
Using Gradle in the Eclipse IDE (https://www.vogella.com/tutorials/EclipseGradle/article.html)
Book Onsite or Virtual Training
Mockito tutorial (https://www.vogella.com/tutorials/Mockito/article.html) (https://www.vogella.com/training/onsite/
The following code defines a minimal test class with one minimal test method.
JAVA
package com.vogella.junit.first;
import org.junit.jupiter.api.Test;
class AClassWithOneJUnitTest {
@Test
void demoTestMethod() {
assertTrue(true);
}
}
You can use assert methods, provided by JUnit or another assert framework, to check an expected result
versus the actual result. Such statement are called asserts or assert statements.
Assert statements typically allow to define messages which are shown if the test fails. You should provide
here meaningful messages to make it easier for the user to identify and fix the problem. This is especially true
if someone looks at the problem, who did not write the code under test or the test code.
Assume you have the following class which you want to test.
ⓘ
(https://www.pixfuture.com/advertisers/?
id0348293521d)
https://www.vogella.com/tutorials/JUnit/article.html 2/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
package com.vogella.junit5;
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/) Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/) public class Calculator {
A test class for the above class could look like the following.
Book Onsite or Virtual Training
(https://www.vogella.com/training/onsite/
package com.vogella.junit5;
Consulting JAVA
(https://www.vogella.com/consulting/)
import static org.junit.jupiter.api.Assertions.assertEquals;
Calculator calculator;
@BeforeEach 1
void setUp() {
calculator = new Calculator();
}
@Test 2
void testMultiply() {
assertEquals(20, calculator.multiply(4, 5), 4
@RepeatedTest(5) 6
4 This is an assert statement which validates that expected and actual value is the same, if not the
message at the end of the method is shown
5 @RepeatedTest defines that this test method will be executed multiple times, in this example 5 times
**/Test*.java 1
**/*Test.java 2
**/*Tests.java 3
**/*TestCase.java 4
1 includes all of its subdirectories and all Java filenames that start with Test .
2 includes all of its subdirectories and all Java filenames that end with Test .
3 includes all of its subdirectories and all Java filenames that end with Tests .
4 includes all of its subdirectories and all Java filenames that end with TestCase .
Therefore, it is common practice to use the Test or Tests suffix at the end of test classes names.
https://www.vogella.com/tutorials/JUnit/article.html 3/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
Messages can be created via lambda expressions, to avoid the overhead in case the construction of the
message is expensive.
JAVA
assertTrue('a' < 'b', () -> "Assertion messages can be lazily evaluated -- "
+ "to avoid constructing complex messages unnecessarily.");
JAVA
import static org.junit.jupiter.api.Assertions.assertThrows;
@Test
void exceptionTesting() {
// set up user
Throwable exception = assertThrows(IllegalArgumentException.class, () ->
user.setAge("23"));
assertEquals("Age must be an Integer.", exception.getMessage());
}
This lets you define which part of the test should throw the exception. The test will still fail if an exception is
thrown outside of this scope.
https://www.vogella.com/tutorials/JUnit/article.html 4/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
import static org.junit.jupiter.api.Assertions.assertTimeout;
import static java.time.Duration.ofSeconds;
import static java.time.Duration.ofMinutes;
@Test
void timeoutNotExceeded() {
assertTimeout(ofMinutes(1), () -> service.doBackup());
}
JAVA
=> org.opentest4j.AssertionFailedError: execution exceeded timeout of 1000 ms by 212 ms
If you want your tests to cancel after the timeout period is passed you can use the
assertTimeoutPreemptively() method.
JAVA
@Test
void timeoutNotExceededWithResult() {
String actualResult = assertTimeoutPreemptively(ofSeconds(1), () -> {
return restService.request(request);
});
assertEquals(200, request.getStatus());
}
JAVA
=> org.opentest4j.AssertionFailedError: execution timed out after 1000 ms
Such a test might be flacky, in case the test server is busy, the test execution might take
longer and therefore such a test might fails from time to time.
https://www.vogella.com/tutorials/JUnit/article.html 5/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
package com.vogella.junit5;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
@BeforeEach
void setUp() throws Exception {
calculator = new Calculator();
}
@RepeatedTest(5)
@DisplayName("Ensure correct handling of zero")
void testMultiplyWithZero() {
Assumptions.assumeFalse(System.getProperty("os.name").contains("Linux"));
You can also write an extension for @ExtendWith which defines conditions under which a test should run.
an Iterable
a Collection
a Stream
JUnit 5 creates and runs all dynamic tests during test execution.
https://www.vogella.com/tutorials/JUnit/article.html 6/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
Methods annotated with @BeforeEach and @AfterEach are not called for dynamic tests. This means, that
Tutorials (https://www.vogella.com/tutorials/) Training
you can’t use thesm (https://www.vogella.com/training/)
to reset Consulting
the test object, if you change it’s state (https://www.vogella.com/consulting/)
in the lambda expression for a dynamic
(https://www.vogella.com/) test.
Company (https://www.vogella.com/company/) Contact us (https://www.vogella.com/contact.html)
GETinstances.
In the following example we define a method to return a Stream of DynamicTest MORE...
Read Premium Content ...
JAVA
package com.vogella.unittest;
(https://learn.vogella.com)
import static org.junit.jupiter.api.Assertions.assertEquals; Book Onsite or Virtual Training
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
(https://www.vogella.com/training/onsite/
import java.util.Arrays; Consulting
import java.util.stream.Stream;
(https://www.vogella.com/consulting/)
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory; TRAINING EVENTS
class DynamicTestCreationTest { Now offering virtual, onsite and
online training
@TestFactory
Stream<DynamicTest> testDifferentMultiplyOperations() { (https://www.vogella.com/training/)
MyClass tester = new MyClass();
int[][] data = new int[][] { { 1, 2, 2 }, { 5, 3, 15 }, { 121, 4, 484 } };
return Arrays.stream(data).map(entry -> {
int m1 = entry[0];
int m2 = entry[1];
int expected = entry[2];
return dynamicTest(m1 + " * " + m2 + " = " + expected, () -> {
assertEquals(expected, tester.multiply(m1, m2));
});
});
}
// class to be tested
class MyClass {
public int multiply(int i, int j) {
return i * j;
}
}
}
We give it the name of the function(s) we want it to call to get it’s test data. The function has to be static and
must return either a Collection, an Iterator, a Stream or an Array. On execution the test method gets called once
for every entry in the data source. In contrast to Dynamic Tests @BeforeEach and @AfterEach methods
will be called for parameterized tests.
https://www.vogella.com/tutorials/JUnit/article.html 7/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
import static org.junit.jupiter.api.Assertions.*;
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/)
import org.junit.jupiter.params.ParameterizedTest; Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/) import org.junit.jupiter.params.provider.MethodSource;
Annotation Description
@MethodSource(names = "genTestData")
JAVA
The result of the named method
is passed as argument to the
test.
@ArgumentsSource(MyArgumentsProvider.class)
JAVA
Specifies a class that provides
the test data. The referenced
class has to implement the
ArgumentsProvider interface.
If you need explicit conversion you can specify a converter with the @ConvertWith annotation. To define
your own converter you have to implement the ArgumentConverter interface. In the following example we
use the abstract SimpleArgumentConverter base class.
https://www.vogella.com/tutorials/JUnit/article.html 8/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
@ParameterizedTest
Tutorials (https://www.vogella.com/tutorials/) Training
@ValueSource(ints (https://www.vogella.com/training/)
= {1, 12, 42}) Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/) void testWithExplicitArgumentConversion(@ConvertWith(ToOctalStringArgumentConverter.class)
String argument) {
Company (https://www.vogella.com/company/) Contact us (https://www.vogella.com/contact.html)
System.err.println(argument);
assertNotNull(argument); GET MORE...
}
Read Premium Content ...
(https://learn.vogella.com)
static class ToOctalStringArgumentConverter extends SimpleArgumentConverter {
@Override
Book Onsite or Virtual Training
protected Object convert(Object source, Class<?> targetType) {
assertEquals(Integer.class, source.getClass(), "Can only convert (https://www.vogella.com/training/onsite/
from Integers.");
assertEquals(String.class, targetType, "Can only convert to String");
Consulting
return Integer.toOctalString((Integer) source);
} (https://www.vogella.com/consulting/)
}
TRAINING EVENTS
Now offering virtual, onsite and
online training
(https://www.vogella.com/training/)
ⓘ
(https://www.pixfuture.com/advertisers/?
id0348293521d)
4. Additional information about JUnit 5 usage
4.1. Nested tests
The @Nested annotation can be used to annotate inner classes which also contain tests. This allows to
group tests and have additional @BeforeEach method, and one @AfterEach methods. When you add
nested test classes to our test class, the following rules must be followed:
The nested test classes are annotated with @Nested annotation so that the runtime can recognize the
nested test classes.
a nested test class can contain Test methods, one @BeforeEach method, and one @AfterEach method.
Because Java doesn’t allow static members in inner classes, a nested class cannot have
additional @BeforeAll and @AfterAll methods. There is no limit for the depth of the class
hierarchy.
Custom implementation - Implement your own MethodOrderer via the orderMethods method, which allows
you to call context.getMethodDescriptors().sort(..)
https://www.vogella.com/tutorials/JUnit/article.html 9/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
package com.vogella.unittest.sortmethods;
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/) Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/) import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
Company (https://www.vogella.com/company/)
import Contact us (https://www.vogella.com/contact.html)
org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder; GET MORE...
Read Premium Content ...
@TestMethodOrder(OrderAnnotation.class)
class OrderAnnotationDemoTest { (https://learn.vogella.com)
Book Onsite or Virtual Training
@Test
@Order(1) (https://www.vogella.com/training/onsite/
void firstOne() {
Consulting
// test something here
} (https://www.vogella.com/consulting/)
@Test
TRAINING EVENTS
@Order(2)
void secondOne() { Now offering virtual, onsite and
// test something here
} online training
(https://www.vogella.com/training/)
}
4.3. Using the @TempDir annotation to create temporary files and paths
The @TempDir annotations allows to annotate non-private fields or method parameters in a test method of
type Path or File. JUnit 5 has registered a `ParameterResolutionException for this
annotation and will create temporary files and paths for the tests. It will also remove the temporary files are
each test.
JAVA
@Test
@DisplayName("Ensure that two temporary directories with same files names and content
have same hash")
void hashTwoDynamicDirectoryWhichHaveSameContent(@TempDir Path tempDir, @TempDir Path
tempDir2) throws IOException {
Files.write(file2, input);
assertTrue(Files.exists(file2), "File should exist");
JAVA
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;
import org.junit.platform.suite.api.SuiteDisplayName;
@Suite
@SuiteDisplayName("JUnit Platform Suite Demo")
@SelectPackages("example")
public class SuiteDemo {
}
At this time of writing you can use the milestone release of 5.8.0-M1 to check this. See the dependencies here
https://search.maven.org/artifact/org.junit.platform/junit-platform-suite-api/1.8.0-M1/jar
https://www.vogella.com/tutorials/JUnit/article.html 10/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
Packaging: jar
Consulting
(https://www.vogella.com/consulting/)
5.2. Configure Maven dependencies for JUnit 5
TRAINING EVENTS
5.2.1. Steps required to configure Maven to use JUnit5
Now offering virtual, onsite and
To use JUnit5 in an Maven project, you need to:
online training
(https://www.vogella.com/training/)
Configure to use Java 11 or higher, as this is required by JUnit5
Configure the maven-surefire-plugin and maven-failsafe-plugin to be at version 2.22.2 so that they can run
JUnit5
Add dependencies to the JUnit5 API and engine for your test code
XML
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<!--1 -->
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
<!--2 -->
<dependencies>
<!-- https://mvnrepository.com/artifact/org.hamcrest/hamcrest-library -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.7.2</version>
<scope>test</scope>
</dependency>
</dependencies>
Once you have done this, you can start using JUnit5 in your Maven project for writing unit tests.
5.2.3. Update Maven settings (in case you are using the Eclipse IDE)
Right-click your pom file, select Maven Update Project and select your project. This triggers an update of your
project settings and dependencies.
https://www.vogella.com/tutorials/JUnit/article.html 11/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
Alternatively you can right-click on your new class in the :_Project Explorer_ or Package
Explorer view and select New Other Java JUnit Test Case.
In the following wizard ensure that the New JUnit Jupiter test flag is selected. The source folder should select
the test directory.
https://www.vogella.com/tutorials/JUnit/article.html 12/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
Press the Next button and select the methods that you want to test.
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/) Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/)
TRAINING EVENTS
Now offering virtual, onsite and
online training
(https://www.vogella.com/training/)
JAVA
package com.vogella.junit.first;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class MyClassTest {
@Test
void testExceptionIsThrown() {
MyClass tester = new MyClass();
assertThrows(IllegalArgumentException.class, () -> tester.multiply(1000, 5));
}
@Test
void testMultiply() {
MyClass tester = new MyClass();
assertEquals(50, tester.multiply(10, 5), "10 x 5 must be 50");
}
}
https://www.vogella.com/tutorials/JUnit/article.html 13/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
The result of the tests are displayed in the JUnit view. In our example one test should be successful and one
Tutorials (https://www.vogella.com/tutorials/) Training
test should show an error.(https://www.vogella.com/training/)
This error is indicated by a red bar. Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/)
TRAINING EVENTS
Now offering virtual, onsite and
online training
(https://www.vogella.com/training/)
Solution
5.8. Review
After a few minutes you should have created a new project, a new class and a new unit test. Congratulations! If
you feel like it, lets improve the tests a bit and write one grouped test.
Solution
Solution
https://www.vogella.com/tutorials/JUnit/article.html 14/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
mins
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/) Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/) In this exercise you learn you to write a JUnit5 test using the Gradle build system and the Eclipse IDE.
TRAINING and
The wizard should also have create the package com.vogella.junit.first in the src/main/java EVENTS
src/main/test
folder. Remove the generated classes from it.
Now offering virtual, onsite and
Modify your build.gradle file to contain at least the following entries. Your build file may contain more
dependencies.
GRADLE
plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2'
}
test {
useJUnitPlatform()
JAVA
package com.vogella.junit.first;
Alternatively you can right-click on your new class in the :_Project Explorer_ or Package
Explorer view and select New Other Java JUnit Test Case.
In the following wizard ensure that the New JUnit Jupiter test flag is selected. The source folder should select
the test directory.
https://www.vogella.com/tutorials/JUnit/article.html 15/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
TRAINING EVENTS
Now offering virtual, onsite and
online training
(https://www.vogella.com/training/)
Press the Next button and select the methods that you want to test.
https://www.vogella.com/tutorials/JUnit/article.html 16/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
TRAINING EVENTS
Now offering virtual, onsite and
online training
(https://www.vogella.com/training/)
JAVA
package com.vogella.junit.first;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class MyClassTest {
@Test
void testExceptionIsThrown() {
MyClass tester = new MyClass();
assertThrows(IllegalArgumentException.class, () -> tester.multiply(1000, 5));
}
@Test
void testMultiply() {
MyClass tester = new MyClass();
assertEquals(50, tester.multiply(10, 5), "10 x 5 must be 50");
}
}
The result of the tests are displayed in the JUnit view. In our example one test should be successful and one
test should show an error. This error is indicated by a red bar.
https://www.vogella.com/tutorials/JUnit/article.html 17/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
TRAINING EVENTS
Now offering virtual, onsite and
online training
(https://www.vogella.com/training/)
Solution
6.7. Review
After a few minutes you should have created a new project, a new class and a new unit test. Congratulations! If
you feel like it, lets improve the tests a bit and write one grouped test.
Solution
Solution
https://www.vogella.com/tutorials/JUnit/article.html 18/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
7.2. Create the data model used for testing TRAINING EVENTS
Create the com.vogella.unittest.model package and copy and paste the following classes on it.
Now offering virtual, onsite and
online training JAVA
package com.vogella.unittest.model;
(https://www.vogella.com/training/)
import java.util.Date;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((releaseDate == null) ? 0 : releaseDate.hashCode());
result = prime * result + ((title == null) ? 0 : title.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Movie other = (Movie) obj;
if (releaseDate == null) {
if (other.releaseDate != null) return false;
} else if (!releaseDate.equals(other.releaseDate)) return false;
if (title == null) {
if (other.title != null) return false;
} else if (!title.equals(other.title)) return false;
return true;
}
JAVA
package com.vogella.unittest.model;
https://www.vogella.com/tutorials/JUnit/article.html 19/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
package com.vogella.unittest.model;
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/) Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/) import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Company (https://www.vogella.com/company/)
import Contact us (https://www.vogella.com/contact.html)
java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; GET MORE...
@Target(ElementType.TYPE)
Read Premium Content ...
@Retention(RetentionPolicy.RUNTIME) (https://learn.vogella.com)
public @interface Magical {
Book Onsite or Virtual Training
} (https://www.vogella.com/training/onsite/
Consulting
(https://www.vogella.com/consulting/)
JAVA
package com.vogella.unittest.model;
TRAINING EVENTS
/** Now offering virtual, onsite and
* Race in Tolkien's Lord of the Rings. online training
*
* @author Florent Biville (https://www.vogella.com/training/)
*/
public enum Race {
@Override
public String toString() {
return "Race [name=" + name + ", immortal=" + immortal + "]";
}
}
JAVA
package com.vogella.unittest.model;
@Magical
public enum Ring {
oneRing, vilya, nenya, narya, dwarfRing, manRing;
https://www.vogella.com/tutorials/JUnit/article.html 20/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
package com.vogella.unittest.model;
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/) Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/) public class TolkienCharacter {
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((race == null) ? 0 : race.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
TolkienCharacter other = (TolkienCharacter) obj;
if (age != other.age) return false;
if (name == null) {
if (other.name != null) return false;
} else if (!name.equals(other.name)) return false;
if (race == null) {
if (other.race != null) return false;
} else if (!race.equals(other.race)) return false;
return true;
}
@Override
public String toString() {
return name + " " + age + " years old " + race.getName();
}
Create the com.vogella.unittest.services package and copy and paste the following classes on it.
https://www.vogella.com/tutorials/JUnit/article.html 21/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
package com.vogella.unittest.services;
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/) Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/) import static com.vogella.unittest.model.Race.DWARF;
import static com.vogella.unittest.model.Race.ELF;
Company (https://www.vogella.com/company/)
import Contact
static us (https://www.vogella.com/contact.html)
com.vogella.unittest.model.Race.HOBBIT;
import static com.vogella.unittest.model.Race.MAIA; GET MORE...
import static com.vogella.unittest.model.Race.MAN;
import static com.vogella.unittest.model.Race.ORC;
Read Premium Content ...
(https://learn.vogella.com)
import java.util.ArrayList;
import java.util.Date;
Book Onsite or Virtual Training
import java.util.HashMap; (https://www.vogella.com/training/onsite/
import java.util.List;
Consulting
import java.util.Map;
(https://www.vogella.com/consulting/)
import com.vogella.unittest.model.Movie;
import com.vogella.unittest.model.Ring;
import com.vogella.unittest.model.TolkienCharacter;
TRAINING EVENTS
Now offering virtual, onsite and
/**
* Init data for unit test online training
*/ (https://www.vogella.com/training/)
public class DataService {
final Movie theFellowshipOfTheRing = new Movie("the fellowship of the Ring", new Date(),
"178 min");
final Movie theTwoTowers = new Movie("the two Towers", new Date(), "179 min");
final Movie theReturnOfTheKing = new Movie("the Return of the King", new Date(), "201
min");
https://www.vogella.com/tutorials/JUnit/article.html 22/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
ArrayList<TolkienCharacter>();
orcsWithHobbitPrisoners.add(guruk);
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/) Consulting (https://www.vogella.com/consulting/)
orcsWithHobbitPrisoners.add(merry);
(https://www.vogella.com/) orcsWithHobbitPrisoners.add(pippin);
return orcsWithHobbitPrisoners;
Company (https://www.vogella.com/company/) Contact us (https://www.vogella.com/contact.html)
}
GET MORE...
public TolkienCharacter getFellowshipCharacter(String name) { Read Premium Content ...
List<TolkienCharacter> list = getFellowship();
(https://learn.vogella.com)
return list.stream().filter(s-> s.equals(name)).findFirst().get();
} Book Onsite or Virtual Training
public Map<Ring, TolkienCharacter> getRingBearers() { (https://www.vogella.com/training/onsite/
Consulting
Map<Ring, TolkienCharacter> ringBearers = new HashMap<>();
(https://www.vogella.com/consulting/)
// ring bearers
ringBearers.put(Ring.nenya, galadriel); TRAINING EVENTS
ringBearers.put(Ring.narya, gandalf);
ringBearers.put(Ring.vilya, elrond); Now offering virtual, onsite and
ringBearers.put(Ring.oneRing, frodo);
online training
return ringBearers;
} (https://www.vogella.com/training/)
https://www.vogella.com/tutorials/JUnit/article.html 23/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
package com.vogella.unittest.services;
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/) Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/) import static com.vogella.unittest.model.Race.HOBBIT;
import static org.junit.jupiter.api.Assertions.assertNotNull;
Company (https://www.vogella.com/company/) Contact
import static us (https://www.vogella.com/contact.html)
org.junit.jupiter.api.Assertions.fail;
GET MORE...
import java.util.List;
Read Premium Content ...
import org.junit.jupiter.api.DisplayName; (https://learn.vogella.com)
import org.junit.jupiter.api.Tag;
Book Onsite or Virtual Training
import org.junit.jupiter.api.Test;
(https://www.vogella.com/training/onsite/
import com.vogella.unittest.model.TolkienCharacter;
Consulting
import com.vogella.unittest.services.DataService;
(https://www.vogella.com/consulting/)
class DataServiceTest {
TRAINING EVENTS
// TODO initialize before each test
DataService dataService; Now offering virtual, onsite and
@Test online training
void ensureThatInitializationOfTolkeinCharactorsWorks() { (https://www.vogella.com/training/)
TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT);
@Test
void ensureThatEqualsWorksForCharaters() {
Object jake = new TolkienCharacter("Jake", 43, HOBBIT);
Object sameJake = jake;
Object jakeClone = new TolkienCharacter("Jake", 12, HOBBIT);
// TODO check that:
// jake is equal to sameJake
// jake is not equal to jakeClone
fail("not yet implemented");
}
@Test
void checkInheritance() {
TolkienCharacter tolkienCharacter = dataService.getFellowship().get(0);
// TODO check that tolkienCharacter.getClass is not a movie class
fail("not yet implemented");
}
@Test
void ensureFellowShipCharacterAccessByNameReturnsNullForUnknownCharacter() {
// TODO imlement a check that dataService.getFellowshipCharacter returns null for an
// unknow felllow, e.g. "Lars"
fail("not yet implemented");
}
@Test
void ensureFellowShipCharacterAccessByNameWorksGivenCorrectNameIsGiven() {
// TODO imlement a check that dataService.getFellowshipCharacter returns a fellow for
an
// existing felllow, e.g. "Frodo"
fail("not yet implemented");
}
@Test
void ensureThatFrodoAndGandalfArePartOfTheFellowsip() {
// TODO check that Frodo and Gandalf are part of the fellowship
fail("not yet implemented");
}
@Test
void ensureThatOneRingBearerIsPartOfTheFellowship() {
// TODO test that at least one ring bearer is part of the fellowship
fail("not yet implemented");
}
https://www.vogella.com/tutorials/JUnit/article.html 24/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
@Tag("slow")
@DisplayName("Minimal
Tutorials (https://www.vogella.com/tutorials/) stress testing: run this test Consulting
Training (https://www.vogella.com/training/) 1000 times to ")
(https://www.vogella.com/consulting/)
void ensureThatWeCanRetrieveFellowshipMultipleTimes() {
(https://www.vogella.com/) dataService = new DataService();
assertNotNull(dataService.getFellowship());
Company (https://www.vogella.com/company/) Contact us should
(https://www.vogella.com/contact.html)
fail("this run 1000 times");
GET MORE...
}
Read Premium Content ...
@Test
void ensureOrdering() { (https://learn.vogella.com)
List<TolkienCharacter> fellowship = dataService.getFellowship(); Book Onsite or Virtual Training
@Test
void ensureThatFellowsStayASmallGroup() {
// TODO Write a test to get the 20 element from the fellowship throws an
// IndexOutOfBoundsException
fail("not yet implemented");
}
Solve the TODO and ensure that all tests can be successfully executed from your IDE. You may find issues in
the DataService with these tests, fix them if you encounter them.
Solution
JAVA
public boolean update() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
}
7.6. Develop a test to constrain the execution time of the long running
method
Create a new test method in your DataServiceTest . Use the assertTimeout assert statement to ensure
that this test does not run longer than 3 seconds.
Solution
https://www.vogella.com/tutorials/JUnit/article.html 25/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
method for
Tutorials (https://www.vogella.com/tutorials/)
email verification
Training (https://www.vogella.com/training/) Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/) 8.1. Create the data model used for testing
Company (https://www.vogella.com/company/)
Create the Contact us (https://www.vogella.com/contact.html)
com.vogella.unittest.email package and copy and paste the following classes on it.
GET MORE...
package com.vogella.unittest.email; Read Premium Content ...
JAVA
(https://learn.vogella.com)
/**
* Validates if the given input is a valid email address.
*
* @param emailPattern The {@link Pattern} used to validate the given email.
* @param email The email to validate.
* @return {@code true} if the input is a valid email. {@code false} otherwise.
*/
public static boolean isValidEmail(CharSequence email) {
return email != null && EMAIL_PATTERN.matcher(email).matches();
}
https://www.vogella.com/tutorials/JUnit/article.html 26/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
package com.vogella.unittest.email;
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/) Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/) import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
Company (https://www.vogella.com/company/) Contact
import static us (https://www.vogella.com/contact.html)
org.junit.jupiter.api.Assertions.fail;
GET MORE...
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
Read Premium Content ...
(https://learn.vogella.com)
class EmailValidatorTest {
Book Onsite or Virtual Training
// TODO Write test for EmailValidator (https://www.vogella.com/training/onsite/
// The names of the methods should give you a pointer what to test for
Consulting
@Test (https://www.vogella.com/consulting/)
public void ensureThatEmailValidatorReturnsTrueForValidEmail() {
}
TRAINING EVENTS
assertTrue(EmailValidator.isValidEmail("lars.vogel@gmail.com"));
@Test
@DisplayName("Ensure that a missiong top level domain returns false")
public void emailValidator_InvalidEmailNoTld_ReturnsFalse() {
fail("Fixme");
}
@Test
public void emailValidator_InvalidEmailDoubleDot_ReturnsFalse() {
fail("Fixme");
}
@Test
public void emailValidator_InvalidEmailNoUsername_ReturnsFalse() {
fail("Fixme");
}
@Test
public void emailValidator_EmptyString_ReturnsFalse() {
fail("Fixme");
}
@Test
public void emailValidator_NullEmail_ReturnsFalse() {
fail("Fixme");
}
Fix all the failing test, unfortunately the test specification is not very good. Try to write reasonable tests which
fit the method name.
8.3. Verify
Run your new test via the IDE. Verify that your code compiles and your test are running via the command line.
8.4. Solution
The following listing contains a possible implementation of the test.
Solution
https://www.vogella.com/tutorials/JUnit/article.html 27/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
package com.vogella.unittest.services;
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/) Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/)
import static com.vogella.unittest.model.Race.HOBBIT;
Company (https://www.vogella.com/company/) Contact
import static us (https://www.vogella.com/contact.html)
org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows; GET MORE...
import static org.junit.jupiter.api.Assertions.fail;
Read Premium Content ...
import org.junit.jupiter.api.Disabled; (https://learn.vogella.com)
import org.junit.jupiter.api.DisplayName;
Book Onsite or Virtual Training
import org.junit.jupiter.api.Test;
(https://www.vogella.com/training/onsite/
import com.vogella.unittest.model.TolkienCharacter;
Consulting
(https://www.vogella.com/consulting/)
public class DataModelAssertThrowsTest {
TRAINING EVENTS
@Test
Now offering
@DisplayName("Ensure that access to the fellowship throws exception outside virtual, onsite and
the valid
range")
void exceptionTesting() { online training
DataService dataService = new DataService(); (https://www.vogella.com/training/)
Throwable exception = assertThrows(IndexOutOfBoundsException.class, () ->
dataService.getFellowship().get(20));
assertEquals("Index 20 out of bounds for length 9", exception.getMessage());
}
@Test
@Disabled("Please fix and enable")
public void ensureThatAgeMustBeLargerThanZeroViaSetter() {
TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT);
// use assertThrows() rule to check that the message is:
// Age is not allowed to be smaller than zero
frodo.setAge(-1);
@Test
@Disabled("Please fix and enable")
public void testThatAgeMustBeLargerThanZeroViaConstructor() {
// use assertThrows() rule to check that an IllegalArgumentException exception is
thrown and
// that the message is:
// "Age is not allowed to be smaller than zero"
Fix the disabled tests and enable them. The name should give a good indication what you have to do test here.
You may discover that the data model does not behave a expected by the test, fix them in this case.
9.2. Verify
Run your update test via the IDE. Verify that your code compiles and your test are running via the command
line with the mvn clean verify .
9.3. Solution
Solution
https://www.vogella.com/tutorials/JUnit/article.html 28/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
package com.vogella.unittest.platform;
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/) Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/) import static org.junit.jupiter.api.Assertions.assertTrue;
TRAINING EVENTS
10. Exercise: Writing nested tests to group testsNow
foroffering
display virtual, onsite and
10.1. Write tests online training
(https://www.vogella.com/training/)
Create the following test.
JAVA
package com.vogella.unittest.nested;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
class UsingNestedTests {
@BeforeEach
void setup() {
list = Arrays.asList("JUnit 5", "Mockito");
}
@Test
void listTests() {
assertEquals(2, list.size());
}
@Test
void checkSecondElement() {
assertEquals(("Mockito"), list.get(1));
}
10.2. Solution
The following listing contains a possible implementation of the test.
Solution
https://www.vogella.com/tutorials/JUnit/article.html 29/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
package com.vogella.unittest.converter;
import java.util.Arrays;
import java.util.stream.Stream;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
class ConverterUtilTest {
@TestFactory
Stream<DynamicTest> ensureThatCelsiumConvertsToFahrenheit() {
return Arrays.stream(celsiusFahrenheitMapping).map(entry -> {
// access celcius and fahrenheit from entry
int celsius = entry[0];
int fahrenheit = entry[1];
return null;
// return a dynamicTest which checks that that the convertion from celcius to
// fahrenheit is correct
});
Stream<DynamicTest> ensureThatFahrenheitToCelsiumConverts() {
return null;
// TODO Write a similar test fahrenheit to celsius
}
}
Fix all the failing test, unfortunately the test specification is not very good. Try to write reasonable tests which
fit the method name.
Show Solution
11.3. Verify
Run your new test via the IDE and ensure that you have 6 tests running succesfull.y
Verify that your code compiles and your test are running via the command line either with ./gradlew
test`or with the `mvn clean verify depending on your build system.
https://www.vogella.com/tutorials/JUnit/article.html 30/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
package com.vogella.unittest.converter;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
class ParameterizedExampleTest {
// class to be tested
class MyClass {
public int multiply(int i, int j) {
return i * j;
}
}
}
Create a new test method in ConverterUtilTest which also uses a parameterized test.
12.3. Verify
Run your new test via the IDE.
convertertestresult10
We're sorry, the image above is broken, please let us know.
Verify that your code compiles and your test are running via the command line with the ./gradlew test or
mvn clean verify command based on your build system.
https://www.vogella.com/tutorials/JUnit/article.html 31/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
@ParameterizedTest
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/)
@ValueSource(strings Consulting
= { "WINDOW", "Microsoft Windows [Version (https://www.vogella.com/consulting/)
10.?]" })
(https://www.vogella.com/) void ensureWindowsStringContainWindow(String name) {
assertTrue(name.toLowerCase().contains("window"));
Company (https://www.vogella.com/company/)
} Contact us (https://www.vogella.com/contact.html)
GET MORE...
@DisplayName("A negative value for year is not supported by the leap year computation.")
@ParameterizedTest(name = "For example, year {0} is not supported.")
Read Premium Content ...
@ValueSource(ints = { -1, -4 }) (https://learn.vogella.com)
void ensureYear(int year) {
assertTrue(year < 0);
Book Onsite or Virtual Training
} (https://www.vogella.com/training/onsite/
Consulting
@ParameterizedTest(name = "{0} * {1} = {2}")
@CsvSource({ "0, 1, 0", "1, 2, 2", "49, 50, 2450", "1, (https://www.vogella.com/consulting/)
100, 100" })
void add(int first, int second, int expectedResult) {
MyClass calculator = new MyClass();
TRAINING EVENTS
assertEquals(expectedResult, calculator.multiply(first, second),
Now offering virtual,
() -> first + " * " + second + " should equal " + expectedResult); onsite and
}
online training
(https://www.vogella.com/training/)
13. Exercise: Using the @TempDir annotation to create
temporary files and paths
In this exercise you learn how to use the @TempDir annotation to let JUnit 5 create files and paths on request
in your test and to automatically remove them after the test.
JAVA
package com.vogella.unittest.file;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
Ensure that the Path given to you by the @TempDir annotation if writable
Ensure that a appending to a file with FileWriter.appendFile which has not yet been created with
FileWriter.createFile throws an exception
Ensure that you can write to the file once you created it
HINT:
https://www.vogella.com/tutorials/JUnit/article.html 32/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
JAVA
@Test
Tutorials (https://www.vogella.com/tutorials/) Training (https://www.vogella.com/training/)
void ensureThatPathFromTempDirISWritable(@TempDir Consulting
Path path) { (https://www.vogella.com/consulting/)
Gradle:
GRADLE
implementation 'javax.inject:javax.inject:1'
JAVA
package com.vogella.unittest.di;
import javax.inject.Inject;
@Inject
String s;
@Inject
public Service() {
}
@Inject
public Service(String s) {
this.s = s;
}
}
Write a test that validates that the Service class only has one constructor annotated with @Inject .
HINT:
14.3. Solution
Solution
https://www.vogella.com/tutorials/JUnit/article.html 33/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
Gradle creates these automatically, if you run the ./gradlew build command and with Maven you run the
Tutorials (https://www.vogella.com/tutorials/) Training
mvn clean verify command. Consulting (https://www.vogella.com/consulting/)
(https://www.vogella.com/training/)
surefire-report:report
(https://www.vogella.com/)
Run this for your project and check the build folder for the generated test reports.
Company (https://www.vogella.com/company/) Contact us (https://www.vogella.com/contact.html)
GET MORE...
16. Exercise: Clone the JUnit5 Github repo and review tests
Read Premium Content ...
(https://learn.vogella.com)
Open JUnit5 Github page (https://github.com/junit-team/junit5) in your browser and clone the repo.
Book Onsite or Virtual Training
Import the project into your favorite IDE and review some of the tests, e.g. the platform-tests contains a
(https://www.vogella.com/training/onsite/
lot of useful tests. Consulting
(https://www.vogella.com/consulting/)
17. Overview of JUnit5 annotations
TRAINING EVENTS
The following table gives an overview of the most important annotations in JUnit 5 from the
org.junit.jupiter.api package. Now offering virtual, onsite and
online training
Table 2. Annotations (https://www.vogella.com/training/)
Annotation Description
@BeforeEach Executed before each test. Used to prepare the test environment, e.g.,
initialize the fields in the test class, configure the environment, etc.
@AfterEach Executed after each test. Used to cleanup the test environment, e.g., delete
temporary data, restore defaults, cleanup expensive memory structures.
@DisplayName(" <Name> that will be displayed by the test runner. In contrast to method
<Name>") names the name can contain spaces to improve readability.
@BeforeAll Annotates a static method which is executed once, before the start of all
tests. It is used to perform time intensive activities, for example, to connect
to a database. Methods marked with this annotation need to be defined as
static to work with JUnit.
@AfterAll Annotates a static method which is executed once, after all tests have been
finished. It is used to perform clean-up activities, for example, to disconnect
from a database. Methods annotated with this annotation need to be
defined as static to work with JUnit.
@Nested Lets you nest inner test classes to group your tests and to have additional
@BeforeEach and @AfterEach methods.
@Tag("<TagName>") Tags a test method, tests in JUnit 5 can be filtered by tag. E.g., run only
tests tagged with "fast".
@ExtendWith Lets you register an Extension class that adds functionality to the tests
18. Conclusion
JUnit 5 makes is easy to write software tests.
The implementation of all these examples and code snippets can be found over on Github
(https://github.com/vogellacompany/tutorials). The Maven examples are located in JUnit with Maven
(https://github.com/vogellacompany/tutorials/tree/master/junitmaven/) and the Gradle examples are located in JUnit
5 with Gradle (https://github.com/vogellacompany/tutorials/tree/master/junitgradle/).
If you need more assistance we offer Online Training (https://learn.vogella.com/) and Onsite training
(https://www.vogella.com/training/) as well as consulting (https://www.vogella.com/consulting/)
https://www.vogella.com/tutorials/JUnit/article.html 34/35
28/02/2023 08:44 JUnit 5 tutorial - Learn how to write unit tests
Company (https://www.vogella.com/company/)
19. JUnit Resources
Contact us (https://www.vogella.com/contact.html)
GET MORE...
JUnit Homepage (http://www.junit.org/) Read Premium Content ...
(https://learn.vogella.com)
JUnit 5 user guide (http://junit.org/junit5/docs/current/user-guide/)
Book Onsite or Virtual Training
(https://www.vogella.com/training/onsite/
Last updated 15:08 17. Aug 2021
Consulting
Legal (https://www.vogella.com/legal.html) Privacy Policy (https://www.vogella.com/privacy.html) Change consent
(https://www.vogella.com/consulting/)
TRAINING EVENTS
Now offering virtual, onsite and
online training
(https://www.vogella.com/training/)
https://www.vogella.com/tutorials/JUnit/article.html 35/35