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,
@BeforeEachand@AfterEachmethod. - Because Java doesn’t allow
staticmembers in inner classes, the@BeforeAlland@AfterAllmethods 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!! ?