Professional Documents
Culture Documents
1 JUnit 5 Introduction-Merged
1 JUnit 5 Introduction-Merged
1 JUnit 5 Introduction-Merged
This lesson introduces JUnit 5, one of the most popular and powerful testing framework for Java.
• Introduction
• What is Junit 5?
• Course Interactivity
Introduction #
Junit was developed by Kent Beck and Erich Gamma. Its first version was
released in 1997. It became one of the most popular testing frameworks in the
Java community due to its ease of use. It is a lightweight testing framework
which allowed Java developers to write unit test cases in Java language. The
recent version released is 5.3.2, which is termed as Junit 5.
What is Junit 5? #
Junit 5 is a powerful and popular Java testing framework. It is composed of
many different modules. These different modules are parts of three sub-
projects as follows:-
Junit Platform
Junit Jupiter
Junit Vintage
The above three projects are core to Junit 5. The architecture of JUnit 5 mostly
comprises of these 3 components/sub-projects. In the next few lessons, we will
take a look at more details of above three sub-projects.
Course Interactivity #
Interactive practice environments are embedded in every lesson to give you a
hands-on learning experience.
Let’s look into an interactive demo below. you don’t need to understand this
for now but here’s how we are going to learn using Educative. Just run below
JUnit 5 code widget and have a look at output without any setup or download.
You can also edit code and run to understand more.
package io.educative.junit5;
import org.junit.jupiter.api.Test;
class HelloWorldTest {
@Test
void checkHelloMsg() {
assertEquals("Hello World", "Hello World");
}
}
This lesson describes Junit 5 architecture, along with their core functionality.
**Junit Platform**
It provides a core foundation to help launching testing frameworks on
JVM. It acts as an interface between JUnit and its clients such as build
tools (`Maven and Gradle`) and IDE's (`Eclipse and IntelliJ`). It
introduces the concept of a `Launcher` which external tools use to
discover, filter, and execute tests.
It also provides the TestEngine API for developing a testing framework that
runs on the JUnit platform. Using TestEngine API , 3rd party testing libraries
such as Spock, Cucumber, and FitNesse can directly plug in and provide their
custom TestEngine.
**Junit Jupiter**
It provides a new programming model and extension model for writing
tests and extensions in Junit 5. It has a whole new annotation to write test
cases in Junit 5. Some of the annotations are `@BeforeEach`,
`@AfterEach`, `@AfterAll`, `@BeforeAll` etc. It implements TestEngine
API provided by Junit Platform so that Junit 5 test can be run.
**Junit Vintage**
The term `Vintage` basically means **classic**. Thus, this sub-project
provides extensive support for writing test cases in JUnit 4 and JUnit 3.
Thus, backward compatibility is been provided by this project.
JUnit 5 Architecture
Q
JUnit 4 test cases are run on JUnit Vintage Engine.
COMPLETED 0%
1 of 1
Q
JUnit 5 test cases are run on JUnit Jupiter Engine.
COMPLETED 0%
1 of 1
In the next lesson, we will learn to create our first JUnit 5 test case.
Building Your First Junit 5 Test
This lesson provides step by step hands-on approach to run JUnit 5 test case on Eclipse IDE.
Project Setup
Please install the following softwares on your machine.
Java 8
JUnit 5 tests will run with Java 8 or above. Please download and install the
latest update of Java 8 or above from the official Oracle web site.
www.oracle.com/technetwork/java/javase/downloads/index.html .
After installing Java, you can check your Java version by running the
following command -
Step 2 - Create a new Java Project. Right click on File --> New --> Java Project
as demonstrated in the figure below.
A new popup window by name “New Java Project” will be opened as shown in
the figure below.
Step 6 - Expand the Junit5 Java project. Right-click on project root. Traverse to
Build Path --> New Source Folder... as shown in the figure below.
Step 7 - A "New Source Folder" popup will be opened as shown in the figure
below.
In order to create a new JUnit 5 test case, perform the following steps:-
Step 11 - Select "New Junit Jupiter test". This will create Junit 5 test case.
FirstJunit5Test.java
package io.educative.junit5;
import org.junit.jupiter.api.Test;
class FirstJunit5Test {
@Test
void test() {
fail("Not yet implemented");
}
It has a method “test()”. This method has an annotation as, @Test. It signifies
that this is a test method in to which we write our code to test.
Step 16 - Right-click on editor window and run as Junit test case, as shown in
the figure below.
The test case fails as shown in fig below. It gives “AssertionFailedError: Not yet
implemented”. It is because in test() method it is written ‘fail(“Not yet
implemented”)’ assertion. This assertion fails the test case as it is not yet
implemented. More on @Test and fail() in upcoming lessons.
In this lesson, we’ll look into a quick review of JUnit’s 5 @Test annotation. This annotation provides a powerful tool
for performing unit testing.
OddEven.java
package com.hubberspot.junit5;
In order to test isEvenNumber() method, we will write a test class which will
have two methods to test the above two scenarios. The test class will be
created in the test folder as discussed in the previous lesson.
In order for the methods created in the test class to be recognized as test
methods, we mark it with @Test annotation. Let’s have a look at the test class
and test methods:-
OddEvenTest.java
OddEven.java
package io.educative.junit5;
import org.junit.jupiter.api.Test;
class OddEvenTest {
@Test
void givenEvenNumber_whenIsEvenIsCalled_thenTrueIsReturned() {
OddEven oddEven = new OddEven();
assertTrue(oddEven.isNumberEven(10));
}
@Test
void givenOddNumber_whenIsEvenIsCalled_thenFalseIsReturned() {
OddEven oddEven = new OddEven();
assertFalse(oddEven.isNumberEven(11));
}
}
You can perform code changes to above code widget, run and practice
different outcomes.
Explanation #
Junit 5 @Test annotation has following characteristics:-
assertTrue() methods take in a boolean value and ensure that value is true. If
a false value is passed, it will fail the test case.
assertFalse() methods take in a boolean value and ensure that value is false.
If a true value is passed, it will fail the test case.
@Test annotation
In the next chapter, we will look into various Assertions JUnit 5 supports.
What is the Assertion in JUnit 5?
• Assertions in JUnit 5
• Assert methods in Assertions API
Assertions in JUnit 5 #
JUnit 5 assertions help us in validating the expected output with the actual
output of a test case. In short, assertions are nothing but static methods that
we call in our tests to verify expected behavior. All JUnit Jupiter assertions are
present in the org.junit.jupiter.Assertions class.
JUnit 5 - Assertions
ﻣﺷﺎرﻛﺔ اﻟﻣﺷﺎھدة ﻻﺣﻘًﺎ
JUnit 5 Assertions
In our previous lessons we have used few assertions such as, fail(),
assertTrue(), assertFalse() and assertEquals() etc. In our upcoming lesson, we
will discuss each and every Assertion in more detail.
assertNull() method
This lesson demonstrates how to use assertNull() method in JUnit 5 to assert test conditions.
• assertNull() method
• Demo
• Class Under Test - StringUtils
• Output
• Explanation -
assertNull() method #
Assertions API provide static assertNull() method. This method helps us in
validating that the particular object is null. This method takes an actual value
and checks whether it is null or not.
There are basically three overloaded methods for assertNull which are
described below:-
assertNull method
Demo #
Step 1 - Create a Java class in Eclipse as discussed in previous lessons.
StringUtils.java
package com.hubberspot.junit5.assertions;
For example -
Step 3 - Create a test class by name, "StringUtilsTest" . This test class will
demonstrate all overloaded assertNull() methods.
StringUtilsTest.java
StringUtils.java
package io.educative.junit5;
@Test
void givenEmptyString_whenReverseIsCalled_thenEmptyStringIsReturned() {
String actual = StringUtils.reverse((""));
String message = "Actual String should be null !!! ";
@Test
void givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned() {
String actual = StringUtils.reverse(("ABCD"));
Supplier<String> messageSupplier = () -> "Actual String should be null !!! "
You can perform code changes to above code widget, run and practice
different outcomes.
Output #
Explanation - #
The order of execution of test cases depends on Junit 5. In StringUtilsTest class
there are 3 @Test methods:-
2. givenEmptyString_whenReverseIsCalled_thenEmptyStringIsReturned() - It
tests the scenario that when “” is provided to reverse() method of
StringUtils class, then “” is returned. Here, return value is empty string
which is not null. So, on line 24 providing assertNull() asserts that
actual value returned is null. Thus, it fails the Junit test case because
actual value returned is “”. In this test case, we are using overloaded
assertNull() method, which takes String message as second argument.
As, this test case doesn’t satisfy assertion condition, it fails and give
" AssertionFailedError: Actual String should be null !!! ==> expected: but
was: <>". It gives AssertionFailedError followed by String message we
provide to assertNull() method.
3. givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned - It
tests the scenario that when ABCD is provided to reverse() method of
StringUtils class, then DCBA is returned. Here, return value is not null.
So, on line 33 providing assertNull() asserts that actual value returned
is null. Thus, it fails the Junit test case because actual value returned is
DCBA. In this test case, we are using overloaded assertNull() method,
which takes Supplier<String> messageSupplier as second argument. As,
this test case doesn’t satisfy assertion condition, it fails and give
" AssertionFailedError: Actual String should be null !!! ==> expected: but
was: <DCBA>". It gives AssertionFailedError followed by lazily evaluates
String message we provide to assertNull() method, as lambda
expression.
This lesson demonstrates how to use assertNotNull() method in JUnit 5 to assert test conditions.
• assertNotNull() method
• Demo
• Class Under Test - StringUtils
• Output
• Explanation -
assertNotNull() method #
Assertions API provide static assertNotNull() method. This method helps us
in validating that particular object is not null. This method takes the actual
value and checks whether it is null or not.
If the actual value is not null then test case will pass.
If the actual value is null then test case will fail.
Demo #
In our previous lesson, we created a class by name, StringUtils. It has the
reverse() method, which reverses the String passed to it.
assertNotNull method
StringUtils.java
package com.hubberspot.junit5.assertions;
For example -
StringUtilsTest2.java
package com.hubberspot.junit5.assertions;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
class StringUtilsTest2 {
@Test
void givenNullString_whenReverseIsCalled_thenNullIsReturned2() {
String actual = StringUtils.reverse((null));
Supplier<String> messageSupplier = () -> "Actual String should not be null !!
@Test
void givenEmptyString_whenReverseIsCalled_thenEmptyStringIsReturned() {
String actual = StringUtils.reverse((""));
@Test
void givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned() {
String actual = StringUtils.reverse(("ABCD"));
StringUtilsTest2.java
StringUtils.java
package io.educative.junit5;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
class StringUtilsTest2 {
@Test
void givenEmptyString_whenReverseIsCalled_thenEmptyStringIsReturned() {
String actual = StringUtils.reverse((""));
@Test
void givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned() {
String actual = StringUtils.reverse(("ABCD"));
You can perform code changes to above code widget, run and practice
different outcomes.
Output #
Explanation - #
The order of execution of test cases depends on Junit 5. In StringUtilsTest2
class there are 4 @Test methods:-
3. givenEmptyString_whenReverseIsCalled_thenEmptyStringIsReturned() - It
tests the scenario that when “” is provided to reverse() method of
StringUtils class, then “” is returned. Here, return value is empty string
which is not null. So, on line 34 providing assertNotNull() asserts that
actual value returned is not null. Thus, it pass the Junit test case because
actual value returned is “” which is not null.
4. givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned - It
tests the scenario that when ABCD is provided to reverse() method of
StringUtils class, then DCBA is returned. Here, return value is not null.
So, on line 42 providing assertNotNull() asserts that actual value
returned is not null. Thus, it pass the Junit test case because actual value
returned is “DCBA” which is not null.
In our upcoming lesson, we will look how we can pass all above test cases
using assertNull() and assertNotNull() methods together.
Using assertNull() and assertNotNull() methods
together
This lesson demonstrates how to use assertNull() and assertNotNull() methods together in JUnit 5 to assert test
conditions.
• Demo
• Class Under Test - StringUtils
• Output
• Explanation -
Demo #
Step 1 - Create a Java class in Eclipse as discussed in previous lessons.
StringUtils.java
package com.hubberspot.junit5.assertions;
if(input.length() == 0) {
return "";
}
For example -
Step 3 - Create a test class by name, “ StringUtilsTest ”. This test class will
demonstrate how to use assertNull() and assertNotNull() methods together
to pass previous lessons failed test cases.
StringUtilsTest.java
StringUtils.java
package io.educative.junit5;
class StringUtilsTest {
@Test
void givenNullString_whenReverseIsCalled_thenNullIsReturned() {
String actual = StringUtils.reverse((null));
assertNull(actual);
}
@Test
void givenEmptyString_whenReverseIsCalled_thenEmptyStringIsReturned() {
String actual = StringUtils.reverse((""));
assertNotNull(actual);
}
@Test
void givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned() {
String actual = StringUtils.reverse(("ABCD"));
assertNotNull(actual);
}
You can perform code changes to above code widget, run and practice
different outcomes.
Output #
Explanation - #
The order of execution of test cases depends on Junit 5. In StringUtilsTest class
there are 3 @Test methods:-
2. givenEmptyString_whenReverseIsCalled_thenEmptyStringIsReturned() - It
tests the scenario that when “” is provided to reverse() method of
StringUtils class, then “” is returned. Here, return value is empty string
which is not null. So, on line 17 providing assertNotNull() asserts that
actual value returned is not null. Thus, it passes the Junit test case
because actual value returned is not null.
3. givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned - It
tests the scenario that when ABCD is provided to reverse() method of
StringUtils class, then DCBA is returned. Here, return value is not null.
So, on line 23 providing assertNotNull() asserts that actual value
returned is not null. Thus, it passes the Junit test case because actual
value returned is not null.
This lesson demonstrates how to use assertEquals() method in JUnit 5 to assert test conditions.
• assertEquals() method
• Demo
• Class Under Test - StringUtils
• Output
• Explanation -
assertEquals() method #
Assertions API provide static assertEquals() method. This method helps us in
validating that actual and expected values are equal. This method uses
equals() to assert the equality of actual and expected value.
If the actual value is equal to expected value then the test case will pass.
If the actual value is not equal to expected value then the test case will
fail.
expected value is not equal to actual value then test case will fail with a
provided message.
assertEquals method
Demo #
Step 1 - Create a Java class in Eclipse as discussed in previous lessons.
StringUtils.java
package com.hubberspot.junit5.assertions;
public class StringUtils {
if(input == null) {
return null;
}
if(input.length() == 0) {
return "";
}
For example -
Step 3 - Create a test class by name, “StringUtilsTest1”. This test class will
demonstrate all overloaded assertEquals() methods.
StringUtilsTest1.java
package com.hubberspot.junit5.assertions;
class StringUtilsTest1 {
@Test
void givenEmptyString_whenReverseIsCalled_thenEmptyStringIsReturned() {
String actual = StringUtils.reverse((""));
String expected = "";
@Test
void givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned() {
String actual = StringUtils.reverse(("ABCD"));
String expected = "DBCA";
@Test
void givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned2() {
String actual = StringUtils.reverse(("1234"));
String expected = "2314";
StringUtilsTest1.java
StringUtils.java
package io.educative.junit5;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
class StringUtilsTest1 {
@Test
void givenEmptyString_whenReverseIsCalled_thenEmptyStringIsReturned() {
String actual = StringUtils.reverse((""));
String expected = "";
// assertEquals without message
assertEquals(expected, actual);
@Test
void givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned() {
String actual = StringUtils.reverse(("ABCD"));
String expected = "DBCA";
@Test
void givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned2() {
String actual = StringUtils.reverse(("1234"));
String expected = "2314";
Output #
Explanation - #
The order of execution of test cases depends on Junit 5. In StringUtilsTest1
class, there are 3 @Test methods:-
1. givenEmptyString_whenReverseIsCalled_thenEmptyStringIsReturned() - It
tests the scenario that when is provided to reverse() method of
StringUtils class, then “” is returned. Here, return value is empty string.
2. givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned - It
tests the scenario that when ABCD is provided to reverse() method of
StringUtils class, then DCBA is returned. Here, return value is DCBA. So,
on line 28 providing assertEquals() asserts that expected value and
actual value returned are equal. Thus, it fails the Junit test case because
expected value is DBCA and actual value returned is DCBA.
3. givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned2 -
It tests the scenario that when 1234 is provided to reverse() method of
StringUtils class, then 4321 is returned. Here, return value is 4321. So, on
line 38 providing assertEquals() asserts that expected value and actual
value returned are equal. Thus, it fails the Junit test case because
expected value is 2314 and actual value returned is 4321.
Though the actual value above returned from reverse() method is correct,
but even if we provide the wrong expected value test case will fail.
StringUtilsTest1.java
StringUtils.java
package io.educative.junit5;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
class StringUtilsTest1 {
@Test
void givenEmptyString_whenReverseIsCalled_thenEmptyStringIsReturned() {
String actual = StringUtils.reverse((""));
String expected = "";
@Test
void givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned() {
String actual = StringUtils.reverse(("ABCD"));
String expected = "DCBA";
@Test
void givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned2() {
String actual = StringUtils.reverse(("1234"));
String expected = "4321";
You can perform code changes to above code widget, run and practice
different outcomes.
This lesson demonstrates how to use assertNotEquals() method in JUnit 5 to assert test conditions.
• assertNotEquals() method
• Demo
• Class Under Test - StringUtils
• Output
• Explanation -
assertNotEquals() method #
Assertions API provide static assertNotEquals() method. This method helps us
in validating that actual and expected values are not equal. This method uses
equals() to assert the in-equality of actual and expected value.
If the actual value is not equal to expected value then the test case will
pass.
If the actual value is equal to expected value then the test case will fail.
expected value is equal to actual value then the test case will fail with the
provided message.
assertNotEquals method
Demo #
Step 1 - Create a Java class in Eclipse as discussed in previous lessons.
StringUtils.java
package com.hubberspot.junit5.assertions;
public class StringUtils {
if(input == null) {
return null;
}
if(input.length() == 0) {
return "";
}
For example -
Step 3 - Create a test class by name, “StringUtilsTest2”. This test class will
demonstrate all overloaded assertNotEquals() methods.
StringUtilsTest2.java
StringUtils.java
package io.educative.junit5;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
class StringUtilsTest2 {
@Test
void givenEmptyString_whenReverseIsCalled_thenEmptyStringIsReturned() {
String actual = StringUtils.reverse((""));
String expected = "1234";
@Test
void givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned() {
String actual = StringUtils.reverse(("ABCD"));
String expected = "DCBA";
@Test
void givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned2() {
String actual = StringUtils.reverse(("1234"));
String expected = "4321";
You can perform code changes to above code widget, run and practice
different outcomes.
Output #
Explanation - #
The order of execution of test cases depends on Junit 5. In StringUtilsTest1
class, there are 3 @Test methods:-
1. givenEmptyString_whenReverseIsCalled_thenEmptyStringIsReturned() - It
tests the scenario that when “” is provided to reverse() method of
StringUtils class, then “” is returned. Here, return value is “”. So, on line
18 providing assertNotEquals() asserts that expected value and actual
value returned not are equal. Thus, it passes the Junit test case because
our expected value which is “1234” and actual value returned are not
equal.
2. givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned - It
tests the scenario that when ABCD is provided to reverse() method of
StringUtils class, then DCBA is returned. Here, return value is DCBA. So,
on line 28 providing assertNotEquals() asserts that expected value and
actual value returned are not equal. Thus, it fails the Junit test case
because expected value is DBCA and actual value returned is DCBA.
3. givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned2 -
It tests the scenario that when 1234 is provided to reverse() method of
StringUtils class, then 4321 is returned. Here, return value is 4321. So, on
line 38 providing assertNotEquals() asserts that expected value and
actual value returned are not equal. Thus, it fails the Junit test case
because expected value is 4321 and actual value returned is 4321.
In this test case, we are using overloaded assertNotEquals() method,
which takes Supplier<String> messageSupplier as second argument. As,
this test case doesn’t satisfy assertion condition, it fails and give
" AssertionFailedError: assertEquals failed ==> expected: not equal but
was: <4321>. It gives AssertionFailedError followed by lazily evaluates
String message we provide to assertNotEquals() method, as lambda
expression.
Though, actual value above returned from reverse() method is correct, but
even if we provide the wrong expected value test case will fail.
StringUtilsTest2.java
StringUtils.java
package io.educative.junit5;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
class StringUtilsTest2 {
@Test
void givenEmptyString_whenReverseIsCalled_thenEmptyStringIsReturned() {
String actual = StringUtils.reverse((""));
String expected = "1234";
@Test
void givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned() {
String actual = StringUtils.reverse(("ABCD"));
String expected = "DCBA";
@Test
void givenNonNullString_whenReverseIsCalled_thenReversedStringIsReturned2() {
String actual = StringUtils.reverse(("1234"));
String expected = "4321";
This lesson demonstrates the importance of the fail method in JUnit 5 Assertions API.
• fail() method
fail() method #
Assertions API provide static fail() method. As soon as, any @Test method
encounters fail() static method, it will fail the test case. The primary usages
of fail() method are as follows -
package io.educative.junit5;
You can perform code changes to above code widget, run and practice
different outcomes.
Step 4 - Run FailedAssertionDemo.java class as Junit Test.
This lesson demonstrates how to use assertTrue method in JUnit 5 to assert test conditions.
• assertTrue() method
• Demo
• Explanation -
assertTrue() method #
Assertions API provide static assertTrue() method. This method helps us in
validating that the actual value supplied to it is true .
Demo #
Let’s look into the usage of the above methods:-
package io.educative.junit5;
import org.junit.jupiter.api.Test;
@Test
public void testAssertTrueWithTrueCondition() {
boolean trueValue = true;
assertTrue(trueValue);
}
@Test
public void testAssertTrueWithFalseCondition() {
boolean falseValue = false;
assertTrue(falseValue);
}
@Test
public void testAssertTrueWithFalseConditionAndMessage() {
boolean falseValue = false;
assertTrue(falseValue, "The actual value is false");
}
@Test
public void testAssertTrueWithFalseConditionAndMessageSupplier() {
boolean falseValue = false;
assertTrue(falseValue, () -> "The actual value is false");
}
@Test
public void testAssertTrueWithBooleanSupplier() {
boolean trueValue = true;
assertTrue(() -> trueValue);
}
@Test
public void testAssertTrueWithBooleanSupplierAndMessage() {
boolean falseValue = false;
assertTrue(() -> falseValue, "The actual value is false");
}
@Test
public void testAssertTrueWithBooleanSupplierAndMessageSupplier() {
boolean falseValue = false;
assertTrue(() -> falseValue, () -> "The actual value is false");
}
}
You can perform code changes to above code widget, run and practice
different outcomes.
Explanation - #
In AssertTrueDemo class there are 7 @Test methods. These 7 methods
demonstrate the working of the above 6 overloaded methods of assertTrue :-
This lesson demonstrates how to use assertFalse method in JUnit 5 to assert test conditions.
• assertFalse() method
• Demo
• Explanation -
assertFalse() method #
Assertions API provide static assertFalse() method. This method helps us in
validating that the actual value supplied to it is false .
assertFalse() method
Demo #
Let’s look into the usage of the above methods.
package io.educative.junit5;
import org.junit.jupiter.api.Test;
@Test
public void testAssertFalseWithFalseCondition() {
boolean falseValue = false;
assertFalse(falseValue);
}
@Test
public void testAssertFalseWithTrueCondition() {
boolean trueValue = true;
assertFalse(trueValue);
}
@Test
public void testAssertFalseWithTrueConditionAndMessage() {
boolean trueValue = true;
assertFalse(trueValue, The actual value is true );
}
@Test
public void testAssertFalseWithTrueConditionAndMessageSupplier() {
boolean trueValue = true;
assertFalse(trueValue, () -> "The actual value is true");
}
@Test
public void testAssertFalseWithBooleanSupplier() {
boolean falseValue = false;
assertFalse(() -> falseValue);
}
@Test
public void testAssertFalseWithBooleanSupplierAndMessage() {
boolean trueValue = true;
assertFalse(() -> trueValue, "The actual value is true");
}
@Test
public void testAssertFalseWithBooleanSupplierAndMessageSupplier() {
boolean trueValue = true;
assertFalse(() -> trueValue, () -> "The actual value is true");
}
}
You can perform code changes to above code widget, run and practice
different outcomes.
Explanation - #
In AssertFalseDemo class, there are 7 @Test methods. These 7 methods
demonstrate the working of the above 6 overloaded methods of assertFalse .
1. testAssertFalseWithFalseCondition() - It asserts the boolean value
provided to assertFalse() method. Here, the actual value passed to it is
false . Thus, it passes the Junit test case because assertFalse asserts that
value passed to it should be false.
This lesson demonstrates how to use assertSame method in JUnit 5 to assert test conditions.
• assertSame() method
• Demo
• Explanation -
assertSame() method #
Assertions API provide static assertSame() method. This method helps us in
validating that expected and actual refer to the exact same object. JUnit uses
== operator to perform this assert.
If the actual and expected value refers to the same object then the test
case will pass.
If the actual and expected value does not refer to the same object then the
test case will fail.
Demo #
Let’s look into the usage of the above methods:-
package io.educative.junit5;
@Test
public void testAssertSameWithSameObject() {
String actual = "hello";
String expected = "hello";
assertSame(expected, actual);
}
@Test
public void testAssertSameWithDifferentObject() {
String actual = "hello";
String expected = "hell";
assertSame(expected, actual);
}
@Test
public void testAssertSameWithDifferentObjectAndMessage() {
String actual = "hello";
String expected = "hell";
assertSame(expected, actual, "The actual value is not same as expected value"
}
@Test
public void testAssertSameWithDifferentObjectAndMessageSupplier() {
String actual = "hello";
String expected = "hell";
assertSame(expected, actual, () -> "The actual value is not same as expected
}
}
Explanation - #
In the AssertSameDemo class, there are 4 @Test methods. These 4 methods
demonstrate the working of the above 3 overloaded methods of assertSame :-
This lesson demonstrates how to use assertNotSame method in JUnit 5 to assert test conditions.
• assertNotSame() method
• Demo
• Explanation -
assertNotSame() method #
Assertions API provide static assertNotSame() method. This method helps us
in validating that expected and actual do not refer to the exact same object.
JUnit uses == operator to perform this assert.
If the actual and expected value refers to the same object then the test
case will fail.
If the actual and expected value does not refer to the same object then the
test case will pass.
Demo #
Let’s look into the usage of the above methods:-
package io.educative.junit5;
@Test
public void testAssertNotSameWithDifferentObject() {
String actual = "hello";
String expected = "hell";
assertNotSame(expected, actual);
}
@Test
public void testAssertNotSameWithSameObject() {
String actual = "hello";
String expected = "hello";
assertNotSame(expected, actual);
}
@Test
public void testAssertNotSameWithSameObjectAndMessage() {
String actual = "hello";
String expected = "hello";
assertNotSame(expected, actual, "The actual value is same as expected value")
}
@Test
public void testAssertNotSameWithSameObjectAndMessageSupplier() {
String actual = "hello";
String expected = "hello";
assertNotSame(expected, actual, () -> "The actual value is same as expected v
}
}
Explanation - #
In the AssertNotSameDemo class, there are 4 @Test methods. These 4 methods
demonstrate the working of the above 3 overloaded methods of
assertNotSame :-
1. testAssertNotSameWithDifferentObject - It asserts that actual value does
not refer to same expected object. Here, the expected value and actual
value passed to assertNotSame() are hell and hello . Thus, it passes the
Junit test case because assertNotSame finds actual and expected objects
not same.
This lesson demonstrates how to use assertArrayEquals method in JUnit 5 to assert test conditions.
• assertArrayEquals() method
• Demo
• Explanation -
assertArrayEquals() method #
Assertions API provide static assertArrayEquals() method. This method helps
us in validating that expected and actual arrays are equal. It has many
overloaded methods to assert different types of array objects.
If the actual and expected arrays are equal then the test case will pass.
If the actual and expected arrays are not equal then the test case will fail.
Demo #
Let’s look into the usage of the above methods:-
JUnit 5 Assertions - assertArrayEquals method
ﻣﺷﺎرﻛﺔ اﻟﻣﺷﺎھدة ﻻﺣﻘًﺎ
assertArrayEquals method
package io.educative.junit5;
import org.junit.jupiter.api.Test;
@Test
public void testAssertArrayEqualsForEqualArrays() {
int[] expected = {1,2,3,4};
int[] actual = {1,2,3,4};
assertArrayEquals(expected, actual);
}
@Test
public void testAssertArrayEqualsForNotEqualArrays() {
int[] expected = {1,2,3,4};
int[] actual = {1,2,3};
assertArrayEquals(expected, actual, "Arrays are not equal.");
}
@Test
public void testAssertArrayEqualsForEqualArraysWithDifferentOrder() {
int[] expected = {1,2,4,3};
int[] actual = {1,2,3,4};
assertArrayEquals(expected, actual, () -> "Arrays order is different");
}
}
Run AssertArrayEqualsDemo class as JUnit Test.
Explanation - #
In the AssertArrayEqualsDemo class, there are 3 @Test methods. These 3
methods demonstrate the working of the above 3 overloaded methods of
assertArrayEquals :-
This lesson demonstrates how to use assertIterableEquals method in JUnit 5 to assert test conditions.
• assertIterableEquals() method
• Demo
• Explanation -
assertIterableEquals() method #
Assertions API provide static assertIterableEquals() method. This method
helps us in validating that expected and actual iterables are deeply equal.
By, deeply equal we mean that number and order of elements in the collection
must be the same, as well as iterated elements must be equal.
Demo #
Let’s look into the usage of the above methods:-
assertIterableEquals method
package io.educative.junit5;
import java.util.ArrayList;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
@Test
public void testAssertIterableEqualsForEqualIterables() {
Iterable<Integer> expected = new ArrayList<>(Arrays.asList(1,2,3,4));
Iterable<Integer> actual = new ArrayList<>(Arrays.asList(1,2,3,4));
assertIterableEquals(expected, actual);
}
@Test
public void testAssertIterableEqualsForNotEqualIterables() {
Iterable<Integer> expected = new ArrayList<>(Arrays.asList(1,2,3,4));
Iterable<Integer> actual = new ArrayList<>(Arrays.asList(1,2,3));
assertIterableEquals(expected, actual, "Iterables are not equal.");
}
@Test
public void testAssertIterableEqualsForEqualIterablesWithDifferentOrder() {
Iterable<Integer> expected = new ArrayList<>(Arrays.asList(1,2,3,4));
Iterable<Integer> actual = new ArrayList<>(Arrays.asList(1,2,4,3));
assertIterableEquals(expected, actual, () -> "Iterables order is different");
}
}
Explanation - #
In the AssertIterableEqualsDemo class, there are 3 @Test methods. These 3
methods demonstrate the working of the above 3 overloaded methods of
assertIterableEquals :-
3. testAssertIterableEqualsForEqualIterablesWithDifferentOrder() - It
asserts that actual and expected iterables are equal. Here, the expected
iterable is arraylist with four elements as, {1,2,3,4} and actual iterable is
arraylist with four elements as, {1,2,4,3}. Thus, it fails the Junit test case
with AssertionFailedError: Iterables order is different ==> iterable
contents differ at index [2], expected: <3> but was: <4> because though
contents of iterables are same they are not in same order. It gives
AssertionFailedError followed by lazily evaluated String message we
provide to assertIterableEquals() method, as lambda expression.
This lesson demonstrates how to use assertThrows method in JUnit 5 to assert test conditions.
• assertThrows() method
• Demo
assertThrows() method #
Assertions API provide static assertThrows() method. This method helps in
asserting that execution of the supplied Executable throws an exception of the
expectedType and returns the exception.
Demo #
Let’s look into the usage of the above methods:-
JUnit 5 Assertions - assertThrows method
ﻣﺷﺎرﻛﺔ اﻟﻣﺷﺎھدة ﻻﺣﻘًﺎ
assertThrows method
package io.educative.junit5;
import java.io.IOException;
import org.junit.jupiter.api.Test;
@Test
public void testAssertThrows() {
assertThrows(ArithmeticException.class, () -> divide(1, 0));
}
@Test
public void testAssertThrowsWithMessage() {
assertThrows(IOException.class, () -> divide(1, 0), "Division by zero !!!");
}
@Test
public void testAssertThrowsWithMessageSupplier() {
assertThrows(IOException.class, () -> divide(1, 0), () -> "Division by zero !
}
This lesson demonstrates how to use assertTimeout method in JUnit 5 to assert timeout conditions.
• assertTimeout() method
• Demo
assertTimeout() method #
Assertions API provide static assertTimeout() method. It is used to test long-
running tasks. If given task inside the test case takes more than the specified
duration, then the test will fail.
The executable provided to the test case will be executed in the same thread
as that of the calling code. Also, the execution of the executable will not be
preemptively aborted if the timeout is exceeded.
Demo #
Let’s look into the usage of the above methods:-
JUnit 5 Assertions - assertTimeout method
ﻣﺷﺎرﻛﺔ اﻟﻣﺷﺎھدة ﻻﺣﻘًﺎ
assertTimeout method
package io.educative.junit5;
import java.time.Duration;
import org.junit.jupiter.api.Test;
@Test
void timeoutNotExceededWithResult() {
// The following assertion succeeds, and returns the supplied object.
String actualResult = assertTimeout(Duration.ofMinutes(3), () -> {
return "result";
});
assertEquals("result", actualResult);
}
@Test
void timeoutNotExceededWithMethod() {
// The following assertion invokes a method reference and returns an object.
String actualGreeting = assertTimeout(Duration.ofMinutes(3), AssertTimeoutDemo::greet
assertEquals("Hello, World!", actualGreeting);
@Test
void timeoutExceeded() {
// The following assertion fails with an error message similar to:
// execution exceeded timeout of 10 ms by 91 ms
assertTimeout(Duration.ofMillis(10), () -> {
// Simulate task that takes more than 10 ms.
Thread.sleep(100);
});
}
This lesson demonstrates how to use assertTimeoutPreemptively method in JUnit 5 to assert timeout conditions.
• assertTimeoutPreemptively() method
• Demo
assertTimeoutPreemptively() method #
Assertions API provide static assertTimeoutPreemptively() method. It is used
to test long-running tasks. If given task inside the test case takes more than the
specified duration, then the test will fail.
The executable provided to the test case will be executed in the different
thread as that of the calling code. Also, the execution of the executable will be
preemptively aborted if the timeout is exceeded.
Demo #
Let’s look into the usage of the above methods:-
JUnit 5 Assertions - assertTimeoutPreemptively method
ﻣﺷﺎرﻛﺔ اﻟﻣﺷﺎھدة ﻻﺣﻘًﺎ
assertTimeoutPreemptively method
package io.educative.junit5;
import java.time.Duration;
import org.junit.jupiter.api.Test;
This lesson demonstrates working of two Lifecycle methods annotated with - @BeforeEach and @AfterEach
Annotation.
package io.educative.junit5;
import org.junit.jupiter.api.Test;
public LifecycleTest() {
System.out.println("LifecycleTest - Constructor got executed !!!");
}
@Test
public void testOne() {
System.out.println("LifecycleTest - testOne() got executed !!!");
}
@Test
public void testTwo() {
System.out.println("LifecycleTest - testTwo() got executed !!!");
}
}
Output of the test
Here, you can see constructor got called two times because there were two
@Test annotated methods. Thus, it proves that each test runs in its own test
class instance.
package io.educative.junit5;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public LifecycleTest() {
System.out.println("LifecycleTest - Constructor got executed !!!");
}
@BeforeEach
public void beforeEach() {
System.out.println("LifecycleTest - beforeEach() got executed !!!");
}
@Test
public void testOne() {
System.out.println("LifecycleTest - testOne() got executed !!!");
}
@Test
public void testTwo() {
System.out.println("LifecycleTest - testTwo() got executed !!!");
@AfterEach
public void afterEach() {
System.out.println("LifecycleTest - afterEach() got executed !!!");
}
As Junit test class has two @Test methods, it executes each of the test methods
in a separate instance of the test class. Thus, it picks the first @Test method in
random order and -
Usually, when we have common setup logic across various test cases, the
common initialization code is placed in the @BeforeEach annotated method
and cleaned up in @AfterEach annotated method.
In the next lesson, we will look into @BeforeAll() and @AfterAll lifecycle
callbacks.
@BeforeAll and @AfterAll Annotation
This lesson demonstrates working of two more Lifecycle methods annotated with - @BeforeAll and @AfterAll
Annotation.
package io.educative.junit5;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@BeforeAll
public static void beforeAll() {
System.out.println("LifecycleTest - beforeAll() got executed !!!");
}
public LifecycleTest() {
System.out.println("LifecycleTest - Constructor got executed !!!");
}
@BeforeEach
public void beforeEach() {
System.out.println("LifecycleTest - beforeEach() got executed !!!");
}
@Test
public void testOne() {
System.out.println("LifecycleTest - testOne() got executed !!!");
}
@Test
public void testTwo() {
System.out.println("LifecycleTest - testTwo() got executed !!!");
}
@AfterEach
public void afterEach() {
System.out.println("LifecycleTest - afterEach() got executed !!!");
}
@AfterAll
public static void afterAll() {
System.out.println("LifecycleTest - afterAll() got executed !!!");
}
You can see in the output of the above test class, that @BeforeAll and
@AfterAll has the following properties:-
This lesson demonstrates how to provide custom display names to test class.
package io.educative.junit5;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@Test
public void test() {
System.out.println("test method got executed!!!");
}
}
@DisplayName with spaces
package io.educative.junit5;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@Test
public void test() {
System.out.println("test method got executed!!!");
}
}
package io.educative.junit5;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@Test
public void test() {
System.out.println( test method got executed!!! );
}
}
Instead of printing actual test class in the Junit tab and reports, it prints string
provided in @DisplayName annotation.
This lesson demonstrates how to provide custom display names to test methods.
package io.educative.junit5;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@Test
public void testWithoutDisplayName() {
System.out.println("test method got executed!!!");
}
@Test
@DisplayName("Custom test name containing spaces")
public void testWithDisplayNameContainingSpaces() {
System.out.println("test method got executed!!!");
}
@Test
@DisplayName("Custom test name containing special characters - !@#$%^&*()_+~`╯°□°)╯"
public void testWithDisplayNameContainingSpecialCharacters() {
System.out.println("test method got executed!!!");
}
@Test
@DisplayName("Custom test name containing emojis - 😱")
public void testWithDisplayNameContainingEmoji() {
System.out.println("test method got executed!!!");
}
}
@DisplayName demonstration
Instead of printing actual test class and test names in the JUnit tab and
reports, it prints string provided in @DisplayName annotation.
@DisplayName annotation
This lesson demonstrates how to use dependency injection (TestInfo Parameter) in Constructor and Test methods.
• ParameterResolver
• TestInfo Parameter
• Code Explanation
ParameterResolver #
In previous JUnit versions, there was limited/no support to allow parameters
in test constructors or methods. One of the major changes in JUnit 5 Jupiter
was that both test constructors and test methods are now allowed to have
parameters. These parameters provide metadata to constructors and test
methods. Thus, allows for greater flexibility and enables Dependency
Injection for test methods and constructors.
Read more -
https://junit.org/junit5/docs/5.3.2/api/org/junit/jupiter/api/extension/package-
summary.html for org.junit.jupiter.api.extension
https://junit.org/junit5/docs/5.3.2/api/org/junit/jupiter/api/extension/Parameter
Resolver.html for ParameterResolver .
TestInfo Parameter #
TestInfoParameterResolver - It is a built-in ParameterResolver. If a method
parameter is of type TestInfo , it signifies that TestInfoParameterResolver will
supply an instance of TestInfo corresponding to the current test as the value
for the parameter.
package io.educative.junit5;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
@BeforeAll
public static void beforeAll(TestInfo testInfo) {
System.out.println("beforeAll() got executed with test info as - ");
System.out.println("Display name - " + testInfo.getDisplayName());
System.out.println("Test Class - " + testInfo.getTestClass());
System.out.println("Test Method - " + testInfo.getTestMethod());
System.out.println("*******************************************");
}
@BeforeEach
public void beforeEach(TestInfo testInfo) {
System.out.println("beforeEach() got executed with test info as - ");
System.out.println("Display name - " + testInfo.getDisplayName());
System.out.println("Test Class - " + testInfo.getTestClass());
System.out.println("Test Method - " + testInfo.getTestMethod());
System.out.println("*******************************************");
}
@Test
@DisplayName("test method by name testOne")
Code Explanation #
The above output of the program demonstrates how TestInfo parameter can
be injected into test constructor and test methods.
It gives information to test methods and constructor about the test class and
test methods.
Here, you can see @BeforeAll annotated method and constructor. It prints
@DisplayName value of test class and also prints test class fully qualified name.
Similarly, TestInfo provides the same info in @AfterAll annotated method.
Since for every new @Test method a new instance of test class is created,
therefore in @BeforeEach , @AfterEach and @Test annotated method, it prints
@DisplayName value of test method and also prints test class fully qualified
name.
• Assumptions in JUnit 5
Assumptions in JUnit 5 #
Assumptions in JUnit 5 is a collection of utility methods that support
conditional test execution based on assumptions. In comparison to failed
assertions, failed assumptions do not result in a test failure; rather, a failed
assumption results in a test being aborted.
Assumptions are typically used whenever it does not make sense to continue
execution of a given test method — for example, if the test depends on
something that does not exist in the current runtime environment.
assumeTrue
assumeFalse
assumingThat
This lesson demonstrates how to use assumeTrue and assumeFalse methods in JUnit 5 to make conditional
assumptions.
• assumeTrue()
• Demo
• assumeFalse()
• Demo
assumeTrue() #
Assumptions API in JUnit 5 has a static utility method called as, assumeTrue() .
It validates the given assumption to true.
Demo #
Let’s look into the usage of the above methods.
package io.educative.junit5;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import org.junit.jupiter.api.Test;
@Test
void testOnDevelopmentEnvironment() {
System.setProperty("ENV", "DEV");
assumeTrue("DEV".equals(System.getProperty("ENV")));
//remainder of test will proceed
}
@Test
void testOnProductionEnvironment() {
System.setProperty("ENV", "PROD");
assumeTrue("DEV".equals(System.getProperty("ENV")), "Assumption failed");
// remainder of test will be aborted
}
}
assumeFalse() #
Assumptions API in JUnit 5 has a static utility method called as assumeFalse() .
It validates the given assumption to false.
Demo #
Let’s look into the usage of the above methods.
package io.educative.junit5;
import org.junit.jupiter.api.Test;
@Test
void testOnDevelopmentEnvironment() {
System.setProperty("ENV", "DEV");
assumeFalse("DEV".equals(System.getProperty("ENV")), "Assumption failed");
//remainder of test will be aborted
}
@Test
void testOnProductionEnvironment() {
System.setProperty("ENV", "PROD");
assumeFalse("DEV".equals(System.getProperty("ENV")));
// remainder of test will proceed
}
}
This lesson demonstrates how to use the assumingThat method in JUnit 5 to make conditional assumptions.
• assumingThat()
• Demo
assumingThat() #
Assumptions API in JUnit 5 has a static utility method called, assumingThat() .
This method takes a boolean assumption and an Executable. It validates the
given assumption and based on its outcome it decides whether to execute an
Executable or not.
Demo #
Let’s look into the usage of the above methods.
package io.educative.junit5;
import org.junit.jupiter.api.Test;
@Test
void testInAllEnvironments() {
System.setProperty("ENV", "DEV");
assumingThat("DEV".equals(System.getProperty("ENV")),
() -> {
// perform these assertions only on the Dev server
System.out.println("Perform these assertions only on the Dev server !!!");
assertEquals(2, 1 + 1);
});
@Test
void testInAllEnvironments2() {
System.setProperty("ENV", "DEV");
assumingThat("PROD".equals(System.getProperty("ENV")),
() -> {
// perform these assertions only on the Prod server
System.out.println("Perform these assertions only on the Prod server !!!");
assertEquals(2, 1 + 1);
});
In the next chapter we will learn about Disable or Enable Tests in JUnit 5.
Disable Test Method and Class - @Disabled
This lesson demonstrates how to disable the test method or a complete test class.
• @Disabled annotation
• @Disabled annotation on Test class
• @Disabled annotation on @Test method
@Disabled annotation #
There are many ways to enable or disable test methods or test class in Junit 5.
@Disabled annotation if applied to the test class, then all the tests present in
the class gets disabled and if applied on the test method, then that test method
is not executed. @Disabled annotation also takes one optional parameter,
which provides a reason for disabling test case for documentation.
package io.educative.junit5;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@Disabled
public class DisabledClassTest {
@Test
void testMethod1() {
assertTrue(4 > 0);
}
@Test
void testMethod2() {
assertFalse(4 < 0);
}
}
package io.educative.junit5;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@Test
void testOnDevelopmentEnvironment() {
System.setProperty("ENV", "DEV");
assertTrue("DEV".equals(System.getProperty("ENV")));
}
This lesson demonstrates how to disable or enable the test method or a complete test class using OS-level
conditions.
package io.educative.junit5;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
@Test
void testOnAllOs() {
assertTrue(3 > 0);
}
@DisabledOnOs(OS.MAC)
@Test
void testDisableOnMacOs() {
assertFalse(0 > 4);
}
@DisabledOnOs(OS.WINDOWS)
@Test
void testDisableOnWindowOs() {
assertFalse(10 > 40);
}
}
Above test program has 3 test methods and @DisabledOnOs is applied on 2 test
methods as -
The above test methods are executed on the Mac operating system. Thus, the
output shows that 1 test method marked as, @DisabledOnOs(OS.MAC) is skipped
for execution.
EnabledOnOsTest.java
package com.hubberspot.junit5.disabled;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
@Test
void testOnAllOs() {
assertTrue(3 > 0);
}
@EnabledOnOs(OS.WINDOWS)
@Test
void testEnabledOnWindowsOs() {
assertFalse(0 > 4);
}
@EnabledOnOs(OS.MAC)
@Test
void testEnabledOnMacOs() {
assertFalse(10 > 40);
}
}
Output of tests
The above test methods are executed on the Mac operating system. Thus, the
output shows that 1 test method marked as, @EnabledOnOs(OS.WINDOWS) is
skipped for execution. It will execute when tests are run on Windows
operating system.
In the next lesson we will learn about DisabledOnJre and EnableOnJre based
conditions.
Java Runtime Environment Conditions -
@DisabledOnJre and @EnabledOnJre
This lesson demonstrates how to disable or enable test methods or a complete test class using JRE level
conditions.
DisabledOnJreTest.java
package com.hubberspot.junit5.disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
@Test
void testOnAllJre() {
assertTrue(3 > 0);
}
@DisabledOnJre(JRE.JAVA_8)
@Test
void testDisableOnJava8() {
assertFalse(0 > 4);
}
@DisabledOnJre(JRE.JAVA_9)
@Test
void testDisableOnJava9() {
assertFalse(10 > 40);
}
}
Above test program has 3 test methods and @DisabledOnJre is applied on 2 test
methods as.
The above test methods are executed on the Java 8 runtime environment.
Thus, the output shows that 1 test method marked as,
@DisabledOnJre(JRE.JAVA_8) is skipped for execution.
EnabledOnJreTest.java
package com.hubberspot.junit5.disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnJre;
import org.junit.jupiter.api.condition.JRE;
@Test
void testOnAllJre() {
assertTrue(3 > 0);
}
@EnabledOnJre(JRE.JAVA_8)
@Test
void testEnabledOnJava8() {
assertFalse(0 > 4);
}
@EnabledOnJre(JRE.JAVA_9)
@Test
void testEnabledOnJava9() {
assertFalse(10 > 40);
}
}
Output of tests
The above test methods are executed on Java 8 runtime environment. Thus,
the output shows that 1 test method marked as, @EnabledOnJre(JRE.JAVA_9) is
skipped for execution. It will execute when tests are run on Java 9 runtime
environment.
System Property Conditions -
@DisabledIfSystemProperty and
@EnabledIfSystemProperty
This lesson demonstrates how to disable or enable test methods or a complete test class using System property
level conditions.
DisabledIfSystemPropertyTest.java
package com.hubberspot.junit5.disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
@Test
void testOnAllSystemProperties() {
assertTrue(3 > 0);
}
@DisabledIfSystemProperty(named="user.name", matches="dinesh")
@Test
void testDisabledIfUserNameMatchesDinesh() {
assertFalse(0 > 4);
}
@DisabledIfSystemProperty(named="os.name", matches="Windows")
@Test
void testDisabledIfOperatingSystemMatchesWindows() {
assertFalse(10 > 40);
}
}
1. testDisabledIfUserNameMatchesDinesh() - Here,
@DisabledIfSystemProperty annotation takes in two attributes such as
named and matches . The value provided to named attribute is "user.name"
and value provided to matches attribute is "dinesh" . It makes the test
method skip to execute if System property by name "user.name" matches
"dinesh" .
2. testDisabledIfOperatingSystemMatchesWindows() - Here,
@DisabledIfSystemProperty annotation takes in two attributes such as
named and matches . The value provided to named attribute is "os.name"
and value provided to matches attribute is "Windows" . It makes the test
method skip to execute if System property by name "os.name" matches
"Windows" .
EnabledIfSystemPropertyTest.java
package com.hubberspot.junit5.disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
@Test
void testOnAllSystemProperties() {
assertTrue(3 > 0);
}
@EnabledIfSystemProperty(named="user.name", matches="dinesh")
@Test
void testEnabledIfUserNameMatchesDinesh() {
assertFalse(0 > 4);
}
@EnabledIfSystemProperty(named="os.name", matches="Windows")
@Test
void testEnabledIfOperatingSystemMatchesWindows() {
assertFalse(10 > 40);
}
}
Output of tests
Above test program has 3 test methods and @EnabledIfSystemProperty is
applied on 2 test methods as -
2. testEnabledIfOperatingSystemMatchesWindows() - Here,
@EnabledIfSystemProperty annotation takes in two attributes such as
named and matches . The value provided to named attribute is "os.name"
and value provided to matches attribute is "Windows" . It makes the test
method enable to execute if System property by name "os.name" matches
"Windows" .
1. user.name - dinesh
2. os.name - Mac OS X
This lesson demonstrates how to disable or enable test methods or a complete test class using Environment
variable conditions.
@DisabledIfEnvironmentVariable and
@EnabledIfEnvironmentVariable #
Junit 5 helps us to disable or enable test cases using various conditions. JUnit
Jupiter API provides annotations in org.junit.jupiter.api.condition package
to enable/disable tests based on a certain condition. The annotations provided
by API can be applied to test methods as well as the class itself. The two
annotations which use system environment properties and specified regex to
disable or enable tests are - @DisabledIfEnvironmentVariable and
@EnabledIfEnvironmentVariable . Let’s take a look at a demo.
DisabledIfEnvironmentVariableTest.java
package com.hubberspot.junit5.disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable;
@Test
void testOnAllEnvironmentVariables() {
assertTrue(3 > 0);
}
@DisabledIfEnvironmentVariable(named="USER", matches="dinesh")
@Test
void testDisabledIfUserMatchesDinesh() {
assertFalse(0 > 4);
}
@DisabledIfEnvironmentVariable(named="HOME", matches="/dummies/home")
@Test
void testDisabledIfHomeMatchesDummyDirectory() {
assertFalse(10 > 40);
}
}
1. testDisabledIfUserMatchesDinesh() - Here,
@DisabledIfEnvironmentVariable annotation takes in two attributes such
as named and matches . The value provided to named attribute is "USER"
and value provided to matches attribute is "dinesh" . It makes the test
method skip to execute if environment variable by name “USER” matches
“dinesh”.
2. testDisabledIfHomeMatchesDummyDirectory() - Here,
@DisabledIfEnvironmentVariable annotation takes in two attributes such
as named and matches . The value provided to named attribute is "HOME"
and value provided to matches attribute is "/dummies/home" . It makes the
test method skip to execute if environment variable by name "HOME"
matches "/dummies/home" .
EnabledIfEnvironmentVariableTest.java
package com.hubberspot.junit5.disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
@Test
void testOnAllEnvironmentVariables() {
assertTrue(3 > 0);
}
@EnabledIfEnvironmentVariable(named="USER", matches="dinesh")
@Test
void testEnabledIfUserMatchesDinesh() {
assertFalse(0 > 4);
}
@EnabledIfEnvironmentVariable(named="HOME", matches="/dummies/home")
@Test
void testEnabledIfHomeMatchesDummyDirectory() {
assertFalse(10 > 40);
}
}
Output of tests
Above test program has 3 test methods and @EnabledIfEnvironmentVariable is
applied on 2 test methods as -
1. USER - dinesh
2. HOME - /Users/dinesh
This lesson demonstrates how to use @Nested annotation to con gure the test hierarchy.
• @Nested Tests
• Explanation
@Nested Tests #
@Nested annotation provides tests creator more functionality to show the
relationship among several groups of tests.
This relationship is achieved by providing nested classes to the main test class.
But, by default nested classes don’t participate in test execution. In order to
provide testing capabilities to nested classes @Nested annotation is used.
package io.educative.junit5;
import java.util.LinkedList;
import java.util.Queue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@DisplayName("A queue")
public class TestingAQueueDemo {
Queue<String> queue; // A Queue of String
@Test
@DisplayName("is null")
void isNotInstantiated() {
assertNull(queue);
}
@Nested
@DisplayName("when new")
class WhenNew {
@BeforeEach
void createNewStack() {
queue = new LinkedList<>();
}
@Test
@DisplayName("is empty")
void isEmpty() {
assertTrue(queue.isEmpty());
}
@Test
@DisplayName("return null element when polled")
void returnNullWhenPolled() {
assertNull(queue.poll());
}
@Test
@DisplayName("return null element when peeked")
void returnNullWhenPeeked() {
assertNull(queue.peek());
}
@Nested
@DisplayName("after offering an element")
class AfterOffering {
@BeforeEach
void offerAnElement() {
queue.offer(anElement);
}
@Test
@DisplayName("it is no longer empty")
void isNotEmpty() {
assertFalse(queue.isEmpty());
}
@Test
@DisplayName("returns the element when polled and is empty")
void returnElementWhenPolled() {
assertEquals(anElement, queue.poll());
assertTrue(queue.isEmpty());
}
@Test
@DisplayName("returns the element when peeked but remains not empty")
void returnElementWhenPeeked() {
assertEquals(anElement, queue.peek());
assertFalse(queue.isEmpty());
}
}
}
}
Explanation #
On running TestingAQueueDemo.java as JUnit Test case, the output generated is
demonstrated in the above image.
In the next chapter, we will discuss about JUnit 5 Integration with Maven.
Create a maven project in Eclipse
• What is Maven?
• Create Maven Project in Eclipse
What is Maven? #
As per Wikipedia - Maven is a build automation tool used primarily for Java
projects. Maven addresses two aspects of building software:
It uses an XML file, also called as pom.xml. This XML file describes the
software project being built, its dependencies on other external modules and
components, the build order, directories, and required plug-ins.
Step 2 - Create a new Maven Project. Right click on File --> New --> Project as
demonstrated in the figure below.
A New Project wizard will be opened. It will show various projects eclipse can
create.
This lesson explains dependencies required to create and run Junit 5 Test cases in Maven.
• Maven Dependencies
Maven Dependencies #
Now, that our Java Maven project is created, we have to make a couple of
changes in the pom.xml file. Expand junit5-maven-starter project and open
the pom.xml file in IDE. Apply the changes as provided in below XML:-
pom.xml
<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>
<junit.jupiter.version>5.3.2</junit.jupiter.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
</depe de cy>
</dependencies>
<build>
<plugins>
<!-- JUnit 5 requires Surefire version 2.22.1 or higher -->
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
</plugins>
</build>
</project>
There are few more dependencies required to run JUnit 4 test cases along with
Junit 5, also writing parameterized tests etc. We will discuss more on this in
the respective lesson.
Create and run JUnit 5 Test Case
This lessons focuses on creating and running JUnit 5 test cases in Maven.
A Java class by name Calculator.java will be created in Eclipse IDE. See the
demonstration of steps below.
Create method inside Calculator class #
Step 1 - Create a method by name, addition() into Calculator class. For this
method, we will write and execute JUnit 5 test cases in Maven.
Step 2 - addition() takes in two integer arguments say, num1 and num2.
Step 3 - It will calculate the sum of num1 and num2 and will return it.
Calculator.java
package com.hubberspot.junit5;
Step 3 - As a best practice, we keep the same Package name of the test class
and src class. Thus, folder names are different but package names are same.
Step 4 - As it is a test class and it provides test methods for Calculator class
therefore, we keep Name of class as, CalculatorTest.
Step 5 - Click Finish.
CalculatorTest.java
package com.hubberspot.junit5;
import org.junit.jupiter.api.Test;
@Test
public void givenTwoNumbers3And4_whenAdditionIsCalled_then7IsReturned() {
Calculator calculator = new Calculator();
assertEquals(7, calculator.addition(3, 4));
}
}
Parameterized Tests Setup
This lesson demonstrates how to setup and run Parameterized Tests in JUnit 5.
JUnit 5 has many types or ways through which we pass different arguments to
test methods.
Setup #
Maven - In order to use parameterized tests, you need to add a dependency for
junit-jupiter-params to maven project. Just add below dependency to
pom.xml which we created in our earlier lesson (Junit 5 Integration with
Maven) -
https://www.educative.io/collection/page/4753235730497536/569341723751219
2/5071437253574656.
pom.xml
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
In our upcoming lesson, we will learn how to use multiple sources to pass
different arguments to @ParameterizedTest methods.
Parameterized Test with @ValueSource
• @ValueSource
@ValueSource #
@ValueSource is one of the simplest ways to pass arguments array to
@ParameterizedTest method. This array can be of following types -
1. short
2. byte
3. int
4. long
5. float
6. double
7. char
8. java.lang.String
9. java.lang.Class
OddEven.java
package com.hubberspot.junit5.parameterized;
public class OddEven {
Step 6 - Let’s pass integer array with different values such as 2,4,6,8,
Integer.MAX_VALUE. There are 5 integer values so @ParameterizedTest will
execute 5 times. In each iteration, it will assert one integer value to check
whether it is even or not. Thus, saving a lot of time spent writing the same
tests for different values again and again.
OddEven.java
OddEvenTest.java
package io.educative.junit5;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
class OddEvenTest {
@ParameterizedTest
@ValueSource(ints = {2,4,6,8,Integer.MAX_VALUE})
void givenANumber_whenIsEvenIsCalled_thenTrueIsReturnedForEvenNumbers(int number) {
OddEven oddEven = new OddEven();
assertTrue(oddEven.isNumberEven(number));
}
• @EnumSource
@EnumSource #
@EnumSource allows us to pass enum constants to @ParameterizedTest method.
Step 1 - Let’s assume that we have to write a parameterized test that takes a
value of the Animal enum as @EnumSource . The Pet enum looks as follows.
Animal.java
package com.hubberspot.junit5.parameterized;
package io.educative.junit5;
Animal.java
import static org.junit.jupiter.api.Assertions.*;
EnumSourceTest.java
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
class EnumSourceTest {
@ParameterizedTest
@EnumSource(Animal.class)
void testEnumSource(Animal animal) {
assertNotNull(animal);
}
• @MethodSource
@MethodSource #
@MethodSource allows us to specify a factory method for different test
arguments. This factory method must be static and can be present in the
same class or any other class too. The factory method should return Stream,
Iterator, Iterable or array of elements to @ParameterizedTest method.
Step 1 - Let’s assume that we have to write a parameterized test that takes
values of the static factory method as @MethodSource .
package io.educative.junit5;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
class MethodSourceTest {
@ParameterizedTest
@MethodSource("parameterProvider")
void testWithSimpleMethodSource(String argument) {
assertNotNull(argument);
}
This lesson demonstrates the use of @CsvSource to pass different arguments to @ParameterizedTest.
• @CsvSource
@CsvSource #
@CsvSource allows you to provide parameter lists as comma-separated
custom-delimiter separated values. @CsvSource annotation uses single quote
along with comma-separated delimiter to distinguish a csv value from others.
For e.g -
Step 1 - Let’s assume that we have to write a parameterized test that takes
values from @CsvSource .
Step 4 - In order to provide different and multiple values through csv source.
We mark this test method with @CsvSource annotation. This annotation takes
comma-separated values which will provide streams/lists of data to
@ParameterizedTest .
package io.educative.junit5;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
class CsvSourceTest {
@ParameterizedTest
@CsvSource({ "one, 1", "two, 2", "'foo, bar', 3" })
void testWithCsvSource(String first, int second) {
assertNotNull(first);
assertNotEquals(0, second);
}
This lesson demonstrates the use of @CsvFileSource to pass different arguments to @ParameterizedTest.
• @CsvFileSource
@CsvFileSource #
@CsvFileSource allows you to use CSV files from the classpath. This csv file
gets picked up from the classpath at the time of running test case and each
line from a CSV file results in one invocation of the parameterized test. We
can also provide a number of lines to skip from top to take comma-separated
values.
Step 1 - Let’s assume that we have to write a parameterized test that takes
values from @CsvFileSource .
capitals.csv
Country, Capital
India, New Delhi
France, Paris
United States, Washington D.C.
United Kingdom, London
CsvFileSourceTest.java
package com.hubberspot.junit5.parameterized;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
class CsvFileSourceTest {
@ParameterizedTest
@CsvFileSource(resources = "/capitals.csv", numLinesToSkip = 1)
void testWithCsvFileSource(String country, String capital) {
assertNotNull(country);
assertNotNull(capital);
}
argument is a String which is capital, therefore the test case ran 4 times. Also,
all string values provided by csv file source are not null, therefore
assertNotNull passes for all values passed.
This lesson demonstrates how to use @RepeatedTest annotation to run tests multiple times.
• @Repeated Tests
• Explanation
@Repeated Tests #
JUnit 5 Jupiter provides the ability to repeat a test a specified number of times.
It is done by simply annotating a method with @RepeatedTest . To this
annotation, we specify a number which is the total number of repetitions
desired. For each and every invocation of a repeated test, it behaves like the
execution of a regular @Test method. Also, each test is executed with support
for the same lifecycle callbacks and extensions. Instead of using @Test
annotation, we use @RepeatedTest annotation.
package io.educative.junit5;
import org.junit.jupiter.api.RepeatedTest;
@RepeatedTest(5)
public void simpleRepeatedTest() {
assertTrue(0 < 5);
}
}
Explanation #
On running RepeatedTestDemo.java as JUnit Test case, the output generated is
demonstrated in the above image.
This lesson demonstrates how to use @RepeatedTest annotation with a custom display name.
RepeatedTestWithDisplayNameDemo.java
package com.hubberspot.junit5.repeated;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.RepeatedTest;
@RepeatedTest(name="{displayName} - {currentRepetition}/{totalRepetitions}",
value = 5)
@DisplayName("Repeated test")
public void repeatedTestWithDisplayName() {
assertTrue(0 < 5);
}
}
package io.educative.junit5;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.RepeatedTest;
@RepeatedTest(name="{displayName} - {currentRepetition}/{totalRepetitions}",
value = 5)
@DisplayName("Repeated test")
public void repeatedTestWithDisplayName() {
assertTrue(0 < 5);
}
Explanation #
On running RepeatedTestWithDisplayNameDemo.java as JUnit Test case, the
output generated is demonstrated in the above image.
The above demo shows that the Junit test case ran with below format -
This marks the end of the course, hope you enjoyed learning.
Conclusion
Next Steps #
This course touched usage of JUnit 5 features. For further reading follow:-
https://junit.org/junit5/docs/current/user-guide/
https://www.udemy.com/course/java-unit-testing-with-junit-5/?
referralCode=14BA45216871EF2F4095
Video Tutorials #
For more on such technologies visit our Youtube channel at -
https://www.youtube.com/user/hubberspot?sub_confirmation=1
Feedback #
For feedback, comments, and suggestions, please contact us at
java.hubberspot@gmail.com