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 –
- All nested test classes must be non-static inner classes.
- Nested classes must be annotated with @Nested annotation.
- There is no limit to the depth of the class hierarchy.
- By default, a nested test class can contain test methods,
@BeforeEach
and@AfterEach
method. - 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!! ?