How to Use the @Before and @After Annotations in JUnit

When writing a unit test suite, there may be some non-test related activities that you need to perform. These activities can take any form. You may need to connect to a database or gather resources before running a test. After running each test case, you may need to free up some resources.


Performing any of these non-testing activities outside of the scope of a unit test class can be tedious, if not impossible. The successful execution of your test class can depend on these activities, so JUnit provides two pairs of annotations to address this issue.


The @BeforeAll annotation

A JUnit test class can have one or more test methods. The @BeforeAll annotation signals that a specific method should be executed before all test methods in a test class. The method associated with this annotation is executed only once (at the beginning of the test), regardless of the number of test methods in the test class.

Any method that uses the @BeforeAll annotation must meet some conditions. These methods must have a void return type, must be public, and cannot be private. The @BeforeAll annotation is ideal for connecting to a database or creating a new file. This article uses a calculator test class to show how you can use the @BeforeAll annotation.

The calculator class

package com.app;
public class Calculator {
public static int add(int num1, int num2) {
return num1 + num2;
}
public static int subtract(int num1, int num2) {
return num1 - num2;
}
public static int multiply(int num1, int num2) {
return num1 * num2;
}
public static int divide(int num1, int num2) {
return num1 / num2;
}
}

The CalculatorTest class

import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;

@DisplayName("Test class demonstrating how to use the before and after annotations.")
class CalculatorTest {
@BeforeAll
public static void powerOnCalculator() {
System.out.println("The calculator is on");
}

@Test
@DisplayName("Testing method that adds two integer values.")
public void testAdd() {
assertEquals(7, Calculator.add(3, 4));
}

@Test
@DisplayName("Testing method that subtracts one integer value from another.")
public void testSubtract() {
assertEquals(6, Calculator.subtract(9, 3));
}

@Test
@DisplayName("Testing method that multiplies two integer values")
public void testMultiply() {
assertEquals(10, Calculator.multiply(5, 2));
}

@Test
@DisplayName("Testing method that divides one integer value by another")
public void testDivide() {
assertEquals(2, Calculator.divide(4, 2));
}
}

In this class, the @BeforeAll annotation works with the powerOnCalculator() method, which prints “The calculator is on” before each test run. Successful test execution prints the following test report:

As you can see, the method associated with the @BeforeAll annotation does not appear in the test report. However, if there is an error in the @BeforeAll annotation method, it will show up in the test report results with an error.

The @BeforeEach annotation

Like the method annotated @BeforeAll, the method annotated @BeforeEach does not appear in the test report. The method annotated with @BeforeEach is executed before each test method in a test class. So if a test class contains two test methods, the @BeforeEach annotation will be executed twice.

import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@DisplayName("Test class demonstrating how to use the before and after annotations.")
class CalculatorTest {
@BeforeAll
public static void powerOnCalculator() {
System.out.println("The calculator is on");
}
@BeforeEach
public void clearCalculator() {
System.out.println("The calculator is ready");
}
@Test
@DisplayName("Testing method that adds two integer values.")
public void testAdd() {
assertEquals(7, Calculator.add(3, 4));
}
@Test
@DisplayName("Testing method that subtracts one integer value from another.")
public void testSubtract() {
assertEquals(6, Calculator.subtract(9, 3));
}
@Test
@DisplayName("Testing method that multiplies two integer values")
public void testMultiply() {
assertEquals(10, Calculator.multiply(5, 2));
}
@Test
@DisplayName("Testing method that divides one integer value by another")
public void testDivide() {
assertEquals(2, Calculator.divide(4, 2));
}
}

Adding the @BeforeEach annotation to the CalculatorTest class produces the following output:

The method associated with the @BeforeEach annotation is executed four times, once before each test method. Note that the @BeforeEach method is not static, has a void return type, and is not private, as these are mandatory provisions. Also note that the method associated with the @BeforeEach annotation executes after the @BeforeAll method.

The @AfterAll annotation

A method with the @AfterAll annotation runs after all test methods in the test class have completed their execution. The @AfterAll annotation is ideal for basic file operations, such as closing a file or detaching from a database. The @AfterAll annotation is the counterpart of the @BeforeAll annotation. Like the @BeforeAll annotation, the @AfterAll annotation must be static, return void, and cannot be private.

@AfterAll
public static void powerOffCalculator() {
System.out.println("The calculator is off");
}

Adding the @AfterAll annotated method to the existing CalculatorTest class gives the following output to the console:

Note that the powerOffCalculator() method, which uses the @AfterAll annotation, is printed at the end of the test class after all test methods have been executed.

The @AfterEach annotation

The @AfterEach annotation is the counterpart of the @BeforeEach annotation. They have the same mandatory provisions, slightly different from those of the @BeforeAll and @AfterAll annotations. What makes the @AfterEach annotation different from the @BeforeEach annotation (apart from their names) is that the @AfterEach method is executed after each test method.

@AfterEach
public void returnResults() {
System.out.println("The results are ready");
}

Running the CalculatorTest class gives the following output on the console:

The output shows that the method associated with the @AfterEach(returnResults) annotation is printed four times. Each execution of the returnResults() method occurs only after the execution of each unit test. This is evident from the fact that the output of the returnResults() method appears after each output of the method associated with the @BeforeEach annotation.

Polish your test suites with annotations

JUnit allows you to handle non-test related processes with the before and after pair annotations. These four annotations are part of a list of several other annotations that add value to your tests. Another note from JUnit is @DisplayName.

The two code examples that display the complete CalculatorTest class use the @DisplayName annotation. The @DisplayName annotation helps you create more meaningful names for your test classes and test methods.

Leave a Reply

Your email address will not be published. Required fields are marked *