JUnit5 @Nested Test class example

In this JUnit tutorial, we will discuss the Nested annotation, its usage, and how it helps us to write better tests.

1. @Nested annotation

@Nested annotation is used to mark the non-static nested class for inclusion in the outer class test run.

It also helps in grouping similar tests together for a better test report generation as well as a better understanding of the tests.

Some rules and features of @Nested annotation are –

  1. All nested test classes must be non-static inner classes.
  2. Nested classes must be annotated with @Nested annotation.
  3. There is no limit to the depth of the class hierarchy.
  4. By default, a nested test class can contain test methods, @BeforeEach and @AfterEach method.
  5. Because Java doesn’t allow static members in inner classes, the @BeforeAll and @AfterAll methods don’t work by default but we will discuss this in detail in the next section of this article.

Let’s implement a basic @Nested annotation example with two nested classes, one of them has @Nested annotation and the other does not have the annotation and observe the output.

class NestedAnnotationTest {

  @Test
  void outermostClassTest() {}

  class MissingNestedAnnotation {
    @Test
    void thisShouldNeverExecute() {}
  }

  @Nested
  class WithNestedAnnotation {
    @Test
    void nestedClassTest() {}
  }
}
Output:-
NestedAnnotationTest [ com.codingeek.NestedAnnotationTest ]
✓ outermostClassTest()
WithNestedAnnotation [ com.codingeek.NestedAnnotationTest$WithNestedAnnotation ]
✓ nestedClassTest()

2. JUnit Callback methods for @Nested classes

We talked about the callback methods like @BeforeAll @BeforeEach @AfterAll @AfterEach in the JUnit test lifecycle, and we can use all of these methods within an @Nested test as well.

@BeforeEach and @AfterEach can be used as usual without any special adjustments.

But, to use @BeforeAll and @AfterAll we have to use @TestInstance(TestInstance.Lifecycle.PER_CLASS) on the nested class. If we do not use this annotation then the methods should be static which in turn needs the Nested class to be static, but we can not do so as @Nested works only with a non-static class.

Let’s implement a nested test class to see how lifecycle events are called for a Nested test.

class NestedAnnotationLifecycleTest {

  @BeforeAll
  static void setUpBeforeAll() {
    System.out.println("OuterClass - Setup @BeforeAll");
  }

  @AfterAll
  static void tearDownAfterAll() {
    System.out.println("OuterClass - Tear down @AfterAll");
  }

  @BeforeEach
  void setUp() {
    System.out.println("OuterClass - Setup");
  }

  @AfterEach
  void tearDown() {
    System.out.println("OuterClass - TearDown");
  }

  @TestInstance(TestInstance.Lifecycle.PER_CLASS)
  @Nested
  class WithLifecycleCalls {

    @BeforeAll
    void setUpBeforeAll() {
      System.out.println("InnerClass - Setup @BeforeAll");
    }

    @AfterAll
    void tearDownAfterAll() {
      System.out.println("InnerClass - Tear down @AfterAll");
    }

    @BeforeEach
    void setUp() {
      System.out.println("InnerClass - Setup");
    }

    @AfterEach
    void tearDown() {
      System.out.println("InnerClass - TearDown");
    }

    @Test
    void nestedClassTest() {}
  }
}
Output:-
OuterClass - Setup @BeforeAll
InnerClass - Setup @BeforeAll
OuterClass - Setup
InnerClass - Setup
InnerClass - TearDown
OuterClass - TearDown
InnerClass - Tear down @AfterAll
OuterClass - Tear down @AfterAll

3. Why @Nested classes?

Some of the benefits of using @Nested tests are

  • @Nested classes group similar tests together which helps the developer in understanding the tests and also verify all the scenarios being tested easily as the developer needs to focus only on the nested class.
  • Setup and teardown methods for a group of tests. In real-world test scenarios, a group of tests needs a similar kind of setup to the other group of tests within the same class which makes it nonoptimal to put it in a single setup or tearDown method.
  • In addition to the point above, we can also declare class variables that can be reused in all the tests of the Nested class only. This again leads to a reduction in test setup for every test and make the test clean, easy to understand, and maintain.

4. Conclusion

In this article, we have discussed the @Nested annotation, how to use this for nested tests, what are the rules, features, and most importantly how it will help us in writing better tests.

Complete code samples are present on Github project.

An investment in knowledge always pays the best interest. I hope you like the tutorial. Do come back for more because learning paves way for a better understanding

Do not forget to share and Subscribe.

Happy coding!! 😊

Recommended -

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x