Discover how a simple structure change can turn your chaotic tests into a clear, easy-to-navigate suite!
Why @Nested inner classes in JUnit? - Purpose & Use Cases
Imagine testing a complex feature with many related parts by writing all tests in one big class. It becomes a messy list where it's hard to find or understand which tests belong to which part.
Manually grouping tests by naming or comments is slow and confusing. You might miss running some tests or misunderstand their purpose. It's like having a cluttered toolbox where you can't find the right tool quickly.
@Nested inner classes let you organize tests inside a main test class in smaller, meaningful groups. This makes tests easier to read, maintain, and run in a logical order, just like having labeled drawers for your tools.
class CalculatorTest {
@Test void addPositive() {}
@Test void addNegative() {}
@Test void subtractPositive() {}
@Test void subtractNegative() {}
}class CalculatorTest { @Nested class AddTests { @Test void positive() {} @Test void negative() {} } @Nested class SubtractTests { @Test void positive() {} @Test void negative() {} } }
It enables clear, logical test structure that mirrors real feature parts, making tests easier to understand and maintain.
Testing a shopping cart where you group tests for adding items, removing items, and calculating totals separately inside nested classes.
Manual test grouping is messy and error-prone.
@Nested classes organize tests into clear, related groups.
This improves readability, maintenance, and test clarity.
Practice
@Nested inner classes in JUnit tests?Solution
Step 1: Understand the role of @Nested
@Nested is used to group related tests inside a main test class, improving structure and readability.Step 2: Compare options
Only To group related test methods together for better organization correctly describes grouping related tests. Other options describe unrelated or incorrect behaviors.Final Answer:
To group related test methods together for better organization -> Option AQuick Check:
@Nested groups tests = A [OK]
- Thinking @Nested runs tests in parallel
- Assuming @Nested replaces main test class
- Believing @Nested removes need for annotations
Solution
Step 1: Identify correct @Nested usage
A nested test class must be annotated with @Nested and contain test methods annotated with @Test.Step 2: Check each option
@Nested class InnerTests { @Test void testMethod() {} } correctly shows @Nested on class and @Test on method. Others misuse annotations or omit them.Final Answer:
@Nested class InnerTests { @Test void testMethod() {} } -> Option CQuick Check:
@Nested on class + @Test on method = B [OK]
- Putting @Test on class instead of method
- Missing @Nested on inner class
- Annotating methods with @Nested
class CalculatorTest {
@BeforeEach void setup() { System.out.println("Setup main"); }
@Test void testAdd() { System.out.println("Test add"); }
@Nested
class MultiplyTests {
@BeforeEach void setup() { System.out.println("Setup nested"); }
@Test void testMultiply() { System.out.println("Test multiply"); }
}
}What will be the output when running the testMultiply method?Solution
Step 1: Understand @BeforeEach in nested classes
Both the outer and nested @BeforeEach methods run before a nested test method.Step 2: Trace method calls for testMultiply
First, outer setup prints "Setup main", then nested setup prints "Setup nested", finally testMultiply prints "Test multiply".Final Answer:
Setup main Setup nested Test multiply -> Option DQuick Check:
Outer + nested setup run before nested test = D [OK]
- Assuming only nested setup runs
- Ignoring outer setup for nested tests
- Expecting only test method output
class OuterTest {
@Nested
class InnerTest {
@Test void testSomething() {}
}
@Test void testOuter() {}
}Which of the following is a problem that will cause the tests NOT to run as expected?Solution
Step 1: Check requirements for @Nested classes
@Nested classes must be non-static inner classes and can have any visibility (default or public).Step 2: Analyze given code
InnerTest is a non-static inner class with @Nested annotation and contains a @Test method. OuterTest has a @Test method too.Final Answer:
No problem; tests will run correctly -> Option BQuick Check:
@Nested inner classes run fine non-static = C [OK]
- Thinking nested classes must be static
- Expecting @Test on nested class itself
- Assuming nested class must be public
@Nested classes to separate addition and subtraction tests. Which of the following code snippets correctly applies @Nested classes with proper setup methods so that the main setup runs before each nested test setup?Solution
Step 1: Understand setup execution order
@BeforeEach in outer class runs before each nested class's @BeforeEach method for every test.Step 2: Analyze options for correct setup and class structure
class CalculatorTest { @BeforeEach void setup() { System.out.println("Main setup"); } @Nested class AddTests { @BeforeEach void setup() { System.out.println("Add setup"); } @Test void testAdd() {} } @Nested class SubtractTests { @BeforeEach void setup() { System.out.println("Subtract setup"); } @Test void testSubtract() {} } } has non-static nested classes and main @BeforeEach before nested @BeforeEach, ensuring main setup runs first. class CalculatorTest { @Nested class AddTests { @BeforeEach void setup() { System.out.println("Add setup"); } @Test void testAdd() {} } @Nested class SubtractTests { @BeforeEach void setup() { System.out.println("Subtract setup"); } @Test void testSubtract() {} } @BeforeEach void setup() { System.out.println("Main setup"); } } places main setup after nested classes, which is allowed but less clear. class CalculatorTest { @BeforeAll static void setup() { System.out.println("Main setup"); } @Nested class AddTests { @BeforeEach void setup() { System.out.println("Add setup"); } @Test void testAdd() {} } @Nested class SubtractTests { @BeforeEach void setup() { System.out.println("Subtract setup"); } @Test void testSubtract() {} } } uses @BeforeAll which runs once, not before each test. class CalculatorTest { @BeforeEach void setup() { System.out.println("Main setup"); } @Nested static class AddTests { @BeforeEach void setup() { System.out.println("Add setup"); } @Test void testAdd() {} } @Nested static class SubtractTests { @BeforeEach void setup() { System.out.println("Subtract setup"); } @Test void testSubtract() {} } } uses static nested classes, which disables outer @BeforeEach running before nested ones.Final Answer:
Option A with non-static nested classes and main @BeforeEach before nested setups -> Option AQuick Check:
Non-static nested + outer @BeforeEach before nested = A [OK]
- Making nested classes static disables outer @BeforeEach
- Using @BeforeAll instead of @BeforeEach for setup
- Placing main setup after nested classes causing confusion
Ready to prove it?
Pass the test and this pattern moves unknown
