Unit Testing Using Junit5 in SpringBoot

Learn via video courses
Topics Covered

Overview

For any software system, three kinds of automated test cases are traditionally written based on the scope and how much functionality they cover.

  • Unit tests
  • Integration tests
  • End-to-end tests

The scope of the test can be well understood from the test pyramid. tests pyramid

The test pyramid is a way of thinking about how different automated tests should be used to create a balanced portfolio. Its essential point is that you should have many more low-level Unit Tests, fewer integration tests, and even fewer end-to-end tests.

The higher we climb the pyramid, the more tests become more complicated and execute slower. The quality of the application is determined by the number of test cases it has and the code it covers.

Introduction to Unit Testing

Unit testing refers to a methodology in which we write code to check a unit's validity.

What is a Unit?

This can be a single method, a class, or multiple classes that can be tested without any network interaction. Unit tests should not make any network operation like calling database or external API.

Benefit of Unit Testing

  • Detects bugs in the early stages of the Software Development Life Cycle (SDLC).
  • Makes sure that the code works as expected.
  • Provides confidence when refactoring the existing code.
  • Helps new developers understand the current behavior of the system.

Introduction to Junit 5

JUnit is a popular Unit Testing Framework that helps Java developers unit test their code.

JUnit was originally developed by Kent Beck and Erich Gamma in 1997. JUnit 5 is the latest version of the software.

Architecture of Junit 5

JUnit 5 is composed of three modules; each has a different purpose.

  • JUnit Jupiter - Jupiter provides an API for developers to write tests and extensions. It also provides a TestEngine API implementation to run these tests on the platform.
  • JUnit Platform - The platform module provides an API based on the interface Launcher. Platform developers like IDEs and test frameworks use it to launch and run tests from their platforms.
  • JUnit Vintage - The Vintage module provides a TestEngine implementation to support backward compatibility for tests written with JUnit 3 and 4.

architecture of junit5

First Unit Test Using JUnit 5

Maven Dependency

Setting up JUnit 5.x.0 is pretty straightforward; we need to add the following dependency:

We usually use test classes to interact with JUnit 5.

A test method has the following characteristics:

  • It should have the org.junit.jupiter.api.Test annotation.
  • It should return void.
  • It may contain parameters.

AAA Pattern for Good Test Case

Unit testing is good, but how can we write good test cases?

There’s a simple and powerful pattern - Arrange-Act-Assert.

Arrange

In the arrange phase, we initialize the piece of the unit we want to test. We prepared data, prepared mock or login if the application is secure.

Act

Act steps should cover the method to be tested. In this step, we invoke the actual method.

Assert

We verify whether the method's behavior matches our expectations in the Assert phase.

Sample test with AAA pattern

Junit 5 Annotations

Annotation can be categorized into three categories Before the test, During the test(optional), and after the test.

Before the Test

  • @BeforeAll Executes exactly once before all test methods.

  • @BeforeEach Executes before each @Test method in this class.

After the Test

  1. @AfterEach Executes after each @Test method.
  2. @AfterAll Executes after all the @Test methods inside the class.

Junit 5 Assertions

Assertions are used to verify the behavior of our test. These methods are provided by the org.junit.jupiter.api.Assertions class.

Below are some popular methods provided by the Assertions class:

Assert MethodPurpose
assertEqualsAssert that expected and actual values are equal.
assertNotEqualsAssert that expected and actual values are not equal.
assertTrueAssert that condition is true.
assertFalseAssert that condition is false.
assertNullAssert that object is null.
assertNotNullAssert that object is not null.
assertSameAssert that expected, and actual values refer to the same object.
assertNotSameAssert that expected, and actual values do not refer to the same object.
assertArrayEqualsAssert that expected and actual arrays are equal.
assertThrowsAssert that execution of the supplied code throws an exception.

Testing Exception

Junit 5 provides the asserThrows assertion for testing the exception.

Parameterized Test

JUnit 5 allows a test to run multiple times with different arguments. They are declared normal tests, but we use the @ParameterizedTest annotation instead of the @Test annotation. This helps test our method with various input data.

The parameterized test uses @ValueSource to provide the input values to the test method. It accepts an array as input, and each element is passed as input to the test method.

Below is an example of this annotation:

The above test will run five times for each input supplied in the @ValueSource annotation.

JUnit Test Suites

Test suites are groups of test runs together. JUnit 5 provides two annotations, @SelectPackages and @SelectClasses, to create test suites.

The above code will run all test cases together under the com.scaler package.

Conclusion

This article covered

  • What is a test pyramid.
  • What is a unit test case and its benefits of it?
  • AAA pattern for writing unit test case
  • Junit 5 test case lifecycle