Effective & Readable Unit Testing With Junit5

Sajith vijesekara
Nerd For Tech
Published in
4 min readMay 18, 2021

--

how to write readable unit testing with junit5

Last week I had to do Tech talk in Arimac & I though to share the content in written medium.

These are the new features I am going to discuss here.

  • Display Names​
  • Group Assertions ​
  • Conditional tests​
  • Parameterized Test(Update)​ ​
  • Dynamic tests​ ​
  • Nested tests​ ​

Here we are going to discuss some of the features are how to write effective Tests in Junit & other aspect we are going to talk is readability.

Setup

For Setup Junit5 in your java project You need java 1.8 & upwards

For My Setup I have created Sample Project. First We have to Add junit-jupiter-engine as dependency.

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.7.1</version>
<scope>test</scope>
</dependency>

Display Names

Display Names Helps to More readability In test cases while in run Time.

Used Annotation

@DisplayName

Example:

@Test
@DisplayName("Check Assertion Display Name")
void testSimpleAssertion() {
assertEquals(1, 1);
}

View

Group Assertions ​

The main advantage of Group Assertions is which helps to run multiple check & one time & It is not blocking if one error occurs.

Let’s See How We did in junit4 First.

@Test
@DisplayName("Junit 4 Way To Run Multiple Tests")
void testOldList() {

final BMICalculatorService bmiCalculatorService = new BMICalculatorService();

float bmi1 = bmiCalculatorService.calculateBMI(55, 161);
float bmi2 = bmiCalculatorService.calculateBMI(75, 161);
float bmi3 = bmiCalculatorService.calculateBMI(65, 135);

assertEquals(UserCategory.NORMAL, bmiCalculatorService.getUserCategory(bmi1));
assertEquals(UserCategory.OVER_WEIGHT, bmiCalculatorService.getUserCategory(bmi2));
assertEquals(UserCategory.OBESE, bmiCalculatorService.getUserCategory(bmi3));
}

The Problem here is if the second assertion failed, It will not be continue to check 3rd case.

Then We doing the same Thing in Junit5

@Test
@DisplayName("BMI Calculator")
void testMBICalculator() {

final BMICalculatorService bmiCalculatorService = new BMICalculatorService();
final float bmi1 = bmiCalculatorService.calculateBMI(55, 161);
float bmi2 = bmiCalculatorService.calculateBMI(75, 161);

Assertions.assertAll(() -> assertEquals(UserCategory.NORMAL, bmiCalculatorService.getUserCategory(bmi1)),
() -> assertEquals(UserCategory.NORMAL, bmiCalculatorService.getUserCategory(bmi2)),
() -> assertEquals(UserCategory.OVER_WEIGHT, bmiCalculatorService.getUserCategory(bmi2)));
}

This is the result when Failed second assertion.It got executed 3rd Times if assertions failed in middle.

Conditional Tests

When We write unit tests, There are some logic's we have to run based on condition . So Rather than check condition in program level We can do it by junit itself.

if the condition fails it will not execute the Test Case.

Parameterized Test

Parameterized Tests came up with junit 4, But In junit 5 there are lot of improvements when writing test cases. @ParameterizedTest is Sub Test of @Test annotation So no need to put both annotations.

These above two Test cases explain how we can use multiple parameters to check the assertions. The Biggest Advantage is Those Parameter values to object types. Read the supported Argument conversions Types

Dynamic Tests

This is the best feature I though which will provided by junit5. The reason is dynamically We can Create Test Cases which helps to do the Test in streams.

Here When stream list of Employee It will create Dynamic Test & gives the results. We have to make sure that test results need to return Stream, Collection, Iterable, Iterator of DynamicTest.

Nested tests​ ​

Netsted Test helps to write Unit Tests more readable way. If our class contains large number of test cases , Then We can organize Test using Nested Tests.

As Example :

@DisplayName("Nested Test Example")
class NetstedExampleTest {

@Test
@DisplayName("Test1")
void testDemo() {
assertEquals(1, 1);
}


@Test
@DisplayName("Test2")
void testLogic2() {
assertEquals(1, 1);
}


@Nested
@DisplayName("Inner Class")
class InnerLogicTest {

@Test
@DisplayName("Layer1")
void testLogic2() {
assertEquals(1, 1);
}


@Nested
@DisplayName("Layer One Class")
class LayerOneTest {

@Test
@DisplayName("Layer2")
void testLogic2() {
assertEquals(1, 1);
}
}
}

}

And Like this way It is easy to read.

And that is all. These Code Samples available in here

--

--

Sajith vijesekara
Nerd For Tech

Technical Lead. Passionate about cloud computing & web security | Freelance Mobile Developer| CKAD | AWS Community Builder 🇱🇰