Java Unit Testing with JUnit 5

Reading Time: 4 minutes

This blog will help you to have a knowledge of Java Unit Testing with JUnit 5.

What is Unit Testing?

  • A Unit Test is a piece of code written by a developer to test certain functionality of code. The Class which we want to test is called System/Class Under Test. The method which is written in the class which the developer wants to test is called Method Under Test. Unit Test instantiates the class under test, executes methods under test, and verifies that it worked as expected. Above all, Java Unit Testing is a simple, open-source Java Unit Testing framework to write and run repeatable tests means the result remains consistent each time you run.
  • Java Unit Testing has been important in the development of test-driven development and is one of a family of unit testing frameworks collectively known as xUnit, which originated with JUnit.

What is TDD?

  • Test-driven development (TDD) is a development technique where you must first write a test that fails before you write new functional code. It is quickly adopt by agile software developers for development of application source code and it is even being adopt by Agile DBAs for database development.

What is JUnit 5?

  • JUnit 5 is most latest version of unit testing among all the JUnits. Java Unit Testing with JUnit 5 supports java 8 and above versions on the other hand includes many different styles of testing .The goal is to create an up-to-date foundation for developer-side testing on the JVM.
  • For a very long time, JUnit has been doing its job perfectly. However, In between, JDK 8 brought very exciting features in java and most notably lambda expressions.

Architecture

JUnit Platform

  • It serves as a foundation for launching testing frameworks on the JVM (Java Virtual Machine), also provides an API to launch tests from either the console, IDEs, or build tools.In addition,It also provides a Console Launcher to launch the platform from the command line and build plugins for Gradle and Maven.

JUnit Jupiter

  • The combination of the new programming model and extension model for writing tests and extensions in JUnit 5. The name has chosen from the fifth planet of our Solar System, which is also the largest one.
  • Above all, it includes new programming and extension models for writing tests. It has all new junit annotations and TestEngine implementation to run tests written with these annotations.

JUnit Vintage

  • A test engine for running JUnit 3 and JUnit 4 based tests on the platform, ensuring the necessary backward compatibility.

JUnit 5 Maven Dependencies

  • To run Junit 5 tests through maven you will need a minimum of two dependencies.
  • Firstly: JUnit Jupiter Engine Dependency
  • Secondly: JUnit Platform Runner Dependency

JUnit Jupiter Engine Dependency

<dependency>
    <groupId> </groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.5.2</version>
</dependency>

JUnit Platform Runner Dependency

<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-runner</artifactId>For More About J
    <version>${junit.platform.version}</version>
    <scope>test</scope>
</dependency>

Annotations

package com.sampleTest;

import org.junit.jupiter.api.*;

public class SampleTest {
        @BeforeAll
        static void beforeAll() {
            System.out.println("**--- Executed once before all test methods in this class ---**");
        }
        @BeforeEach
        void beforeEach() {
            System.out.println("**--- Executed before each test method in this class ---**");
        }
        @Test
        void testMethod1() {
            System.out.println("**--- Test method1 executed ---**");
        }
        @DisplayName("Test method2 with condition")
        @Test
        void testMethod2() {
            System.out.println("**--- Test method2 executed ---**");
        }
        @Test
        @Disabled("implementation pending")
        void testMethod3() {
            System.out.println("**--- Test method3 executed ---**");
        }
        @AfterEach
        void afterEach() {
            System.out.println("**--- Executed after each test method in this class ---**");
        }
        @AfterAll
        static void afterAll() {
            System.out.println("**--- Executed once after all test methods in this class ---**");
        }
}

Output

**--- Executed once before all test methods in this class ---**
**--- Executed before each test method in this class ---**
**--- Test method1 executed ---**
**--- Executed after each test method in this class ---**
**--- Executed before each test method in this class ---**
**--- Test method2 executed ---**
**--- Executed after each test method in this class ---**

implementation pending
**--- Executed once after all test methods in this class ---**

Assertions

  • Assertions help in validating the expected output with actual output of a testcase. To keep things simple, all JUnit Jupiter assertions are static methods in the org.junit.jupiter.Assertions class For Example: assertEquals() , assertNotEquals()
void testCase() 
{
    //Test will pass
    Assertions.assertNotEquals(3, Calculator.add(2, 2));
      
    //Test will fail 
    Assertions.assertNotEquals(4, Calculator.add(2, 2), "Calculator.add(2, 2) test failed");
      
    //Test will fail 
    Supplier<String> messageSupplier  = ()-> "Calculator.add(2, 2) test failed";
    Assertions.assertNotEquals(4, Calculator.add(2, 2), messageSupplier);
}

Assumptions

  • The Assumptions class provides static methods to support conditional test execution based on assumptions. A failed assumption results in a test being abort. Assumptions are typically use whenever it does not make sense to continue the execution of a given test method. In the test report, these tests will be mark as passed.
  • JUnit jupiter Assumptions class has two such methods for example: assumeFalse(), assumeTrue().
public class AppTest {
    @Test
    void testOnDev() 
    {
        System.setProperty("ENV", "DEV");
        Assumptions.assumeTrue("DEV".equals(System.getProperty("ENV")), AppTest::message);
    }
      
    @Test
    void testOnProd() 
    {
        System.setProperty("ENV", "PROD");
        Assumptions.assumeFalse("DEV".equals(System.getProperty("ENV")));  
    }
      
    private static String message () {
        return "TEST Execution Failed :: ";
    }
}

Backward Compatibility for JUnit 3 or JUnit 4

  • JUnit 4 has been here for a quite long time and there are numerous tests written on Junit 4. The JUnit Jupiter needs to support those tests as well. For this purpose, the JUnit Vintage sub-project is developed.
  • JUnit Vintage provides a TestEngine implementation for running JUnit 3 and JUnit 4 based tests on the JUnit 5 platform.

Conclusion

  • To sum up, JUnit 5 is still in development. It seems so exciting and feature-rich. And now it’s open for extension by third-party tools and APIs. As a test writer, you may not feel that much different but when you will go for its extension or try to develop an IDE plugin, you will praise it.

References

https://www.tutorialspoint.com/junit/index.htm