2.11. Nested Tests

@Nested tests give the test writer more capabilities to express the relationship among several groups of tests. Here’s an elaborate example.

Nested test suite for testing a stack

  1. import static org.junit.jupiter.api.Assertions.assertEquals;
  2. import static org.junit.jupiter.api.Assertions.assertFalse;
  3. import static org.junit.jupiter.api.Assertions.assertThrows;
  4. import static org.junit.jupiter.api.Assertions.assertTrue;
  5. import java.util.EmptyStackException;
  6. import java.util.Stack;
  7. import org.junit.jupiter.api.BeforeEach;
  8. import org.junit.jupiter.api.DisplayName;
  9. import org.junit.jupiter.api.Nested;
  10. import org.junit.jupiter.api.Test;
  11. @DisplayName("A stack")
  12. class TestingAStackDemo {
  13. Stack<Object> stack;
  14. @Test
  15. @DisplayName("is instantiated with new Stack()")
  16. void isInstantiatedWithNew() {
  17. new Stack<>();
  18. }
  19. @Nested
  20. @DisplayName("when new")
  21. class WhenNew {
  22. @BeforeEach
  23. void createNewStack() {
  24. stack = new Stack<>();
  25. }
  26. @Test
  27. @DisplayName("is empty")
  28. void isEmpty() {
  29. assertTrue(stack.isEmpty());
  30. }
  31. @Test
  32. @DisplayName("throws EmptyStackException when popped")
  33. void throwsExceptionWhenPopped() {
  34. assertThrows(EmptyStackException.class, stack::pop);
  35. }
  36. @Test
  37. @DisplayName("throws EmptyStackException when peeked")
  38. void throwsExceptionWhenPeeked() {
  39. assertThrows(EmptyStackException.class, stack::peek);
  40. }
  41. @Nested
  42. @DisplayName("after pushing an element")
  43. class AfterPushing {
  44. String anElement = "an element";
  45. @BeforeEach
  46. void pushAnElement() {
  47. stack.push(anElement);
  48. }
  49. @Test
  50. @DisplayName("it is no longer empty")
  51. void isNotEmpty() {
  52. assertFalse(stack.isEmpty());
  53. }
  54. @Test
  55. @DisplayName("returns the element when popped and is empty")
  56. void returnElementWhenPopped() {
  57. assertEquals(anElement, stack.pop());
  58. assertTrue(stack.isEmpty());
  59. }
  60. @Test
  61. @DisplayName("returns the element when peeked but remains not empty")
  62. void returnElementWhenPeeked() {
  63. assertEquals(anElement, stack.peek());
  64. assertFalse(stack.isEmpty());
  65. }
  66. }
  67. }
  68. }
Only non-static nested classes (i.e. inner classes) can serve as @Nested test classes. Nesting can be arbitrarily deep, and those inner classes are considered to be full members of the test class family with one exception: @BeforeAll and @AfterAll methods do not work by default. The reason is that Java does not allow static members in inner classes. However, this restriction can be circumvented by annotating a @Nested test class with @TestInstance(Lifecycle.PER_CLASS) (see Test Instance Lifecycle).