JUnit Annotations

Filed Under: JUnit

JUnit testing framework is built on annotations. JUnit 5 is a major upgrade from JUnit 4. There are different modules and we need JUnit Platform and JUnit Jupiter API to create and run the test cases for our java project.

JUnit Annotations

Let’s look at the most important annotations in JUnit 5 Jupiter API. Most of them are located in the org.junit.jupiter.api package in the junit-jupiter-api module.

@Test

@Test annotation is used to specify that the annotated method is a test method.

@Test methods must not be private or static. @Test methods must not return a value.

@Test methods may optionally declare parameters to be resolved by ParameterResolvers.

Here is a simple example of the @Test method.


@Test
void testMethod1() {
  System.out.println("test method");
}

@ParameterizedTest

JUnit @ParameterizedTest annotation is used to run a test method multiple times with different arguments. This annotation is defined in junit-jupiter-params module. This annotation also requires us to define a source for the method arguments. Some of the annotations that can be used as arguments provider are ValueSource, EnumSource, MethodSource, CsvSource, and CsvFileSource. Here is a simple example of using @ParameterizedTest annotation.


@ParameterizedTest
@ValueSource(strings = { "1", "2", "3" })
void test_ValueSource_String(String s) {
	assertTrue(Integer.parseInt(s) < 5);
}

You can read more about them at JUnit Parameterized Tests.

@RepeatedTest

JUnit @RepeatedTest annotation is used to repeat a test specified number of times.


@RepeatedTest(5)
void test() {
	System.out.println("@RepeatedTest Simple Example");
}

Above test will be executed 5 times, read more at JUnit Repeated Tests.

@TestFactory

JUnit @TestFactory annotation coupled with DynamicTest can be used to create a test factory method. JUnit @TestFactory methods must not be private or static. These methods must return a Stream, Collection, Iterable, or Iterator of DynamicNode instances. Here is a simple example of the @TestFactory method to create dynamic tests at runtime.


@TestFactory
Collection<DynamicTest> dynamicTests() {
    return Arrays.asList(
        dynamicTest("simple dynamic test", () -> assertTrue(true)),
        dynamicTest("My Executable Class", new MyExecutable()),
        dynamicTest("simple dynamic test-2", () -> assertTrue(true))
    );
}

We can generate dynamic tests for a class method too, read more at JUnit 5 Dynamic Tests.

@TestInstance

We can use @TestInstance annotation to change the lifecycle behavior of a class. By default, JUnit creates a new instance of each test class before executing each test method. This behavior is called “per-method” test instance lifecycle. We can change it to “per-class” mode for faster processing of tests because a new test instance will be created once per test class.


@TestInstance(Lifecycle.PER_CLASS)
class InnerClass {
//tests
}

@DisplayName

This annotations is used to define a custom display name for test class and methods.


@DisplayName("MyTestClass")
public class DisplayNameTest {
}

@Test
@DisplayName("Example Test Method with No Business Logic")
void test() {
	assertTrue(3 > 0);
}

You can read more about it at JUnit Display Name.

@Nested

JUnit Jupiter @Nested annotation is used to mark a nested class to be included in the test cases. By default, nested classes are not scanned for test methods. The nested class should be non-static. You can read more about them at JUnit Nested Tests.

@Disabled

JUnit @Disabled annotation is the easiest way to disable a test. It can be applied to a test method as well as on the Class itself.


@Test
@Disabled
void test() {
	assertTrue(true);
}

@Disabled("Explicitly Disabled")
class DisabledTests {
//all tests disabled
}

JUnit Jupiter provides various annotations to enable or disable a test based on specified condition. Some of them are @DisabledOnOs, @EnabledOnOs, @DisabledOnJre, @EnabledOnJre, @DisabledIfEnvironmentVariable, @EnabledIfEnvironmentVariable, @DisabledIfSystemProperty, @EnabledIfSystemProperty, @DisabledIf, and @EnabledIf.

You can get complete details about these annotations at JUnit Disable Enable Tests.

JUnit Lifecycle Callback Annotations

There are four annotations that we can use to define callback methods at various stages of test cases execution.

@BeforeEach

Denotes that the annotated method should be executed before each @Test, @RepeatedTest, @ParameterizedTest, or @TestFactory method in the current class.

@AfterEach

Used to define a method to be executed after each test method in the current class. These methods gets executed for each tests in the nested classes too.

@BeforeAll

Used to define a method to be executed before all test methods in the current class. This method must be static, unless TestInstance is set to “per-class” mode.

@AfterAll

This annotation is used to define a method to be executed after all test methods in the current class. This method must be static, unless TestInstance is set to “per-class” mode.


@BeforeAll
static void setUpBeforeClass() throws Exception {
	System.out.println("Set Up Before Class - @BeforeAll");
}

@AfterAll
static void tearDownAfterClass() throws Exception {
	System.out.println("Tear Down After Class - @AfterAll");
}

@BeforeEach
void setUp() throws Exception {
	System.out.println("Set Up @BeforeEach");
}

@AfterEach
void tearDown() throws Exception {
	System.out.println("Tear Down @AfterEach");
}

JUnit lifecycle callback methods can be used to initialize or destroy resources for the test. They can also be used to reset any shared variables before test cases are executed.

Summary

JUnit testing framework is built on Java annotations. They are an integral part of JUnit framework and helps us in writing tests easily with less code.

You can check out more JUnit 5 examples from our GitHub Repository project.

Leave a Reply

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

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages