0
0
JunitHow-ToBeginner ยท 4 min read

How to Use @Nested in JUnit for Structured Testing

Use @Nested in JUnit to create inner test classes that group related tests together, improving test organization and readability. Each @Nested class can have its own setup and tests, running as part of the outer test class.
๐Ÿ“

Syntax

The @Nested annotation is placed on a non-static inner class inside a test class. This inner class contains related test methods and can have its own lifecycle methods like @BeforeEach and @AfterEach.

Example parts:

  • @Nested: marks the inner class as a nested test class.
  • Inner class: groups related tests logically.
  • Test methods: annotated with @Test inside the nested class.
java
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class OuterTest {

    @Nested
    class InnerGroup {

        @BeforeEach
        void setup() {
            // setup code for this group
        }

        @Test
        void testOne() {
            // test code
        }
    }
}
๐Ÿ’ป

Example

This example shows a calculator test with nested classes grouping addition and subtraction tests separately. Each nested class has its own setup and tests.

java
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.*;

class CalculatorTest {

    Calculator calculator;

    @BeforeEach
    void init() {
        calculator = new Calculator();
    }

    @Nested
    class AdditionTests {

        @BeforeEach
        void setup() {
            // Setup specific to addition tests if needed
        }

        @Test
        void addsTwoPositiveNumbers() {
            assertEquals(5, calculator.add(2, 3));
        }

        @Test
        void addsNegativeAndPositive() {
            assertEquals(0, calculator.add(-2, 2));
        }
    }

    @Nested
    class SubtractionTests {

        @Test
        void subtractsSmallerFromLarger() {
            assertEquals(1, calculator.subtract(3, 2));
        }

        @Test
        void subtractsNegativeNumber() {
            assertEquals(5, calculator.subtract(3, -2));
        }
    }
}

class Calculator {
    int add(int a, int b) {
        return a + b;
    }

    int subtract(int a, int b) {
        return a - b;
    }
}
Output
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
โš ๏ธ

Common Pitfalls

  • Not making the nested class non-static: @Nested classes must be non-static inner classes.
  • Using @BeforeAll inside nested classes without @TestInstance(Lifecycle.PER_CLASS) causes errors.
  • Expecting nested tests to run independently outside the outer class context.

Correct usage requires the nested class to be non-static and lifecycle annotations to be compatible.

java
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

class WrongNestedTest {

    // This is wrong because nested class is static
    @Nested
    static class StaticNested {
        @Test
        void test() {}
    }

    // Correct way:
    @Nested
    class NonStaticNested {
        @Test
        void test() {}
    }
}
๐Ÿ“Š

Quick Reference

@Nested helps organize tests by grouping related test methods inside inner classes. Use it to:

  • Improve test readability
  • Separate test setup per group
  • Run nested tests as part of the outer test class

Remember: nested classes must be non-static and can have their own lifecycle methods.

โœ…

Key Takeaways

Use @Nested on non-static inner classes to group related tests logically.
Each nested class can have its own setup and teardown methods.
Nested tests run as part of the outer test class execution.
Avoid static nested classes with @Nested; they must be non-static.
Use @TestInstance(Lifecycle.PER_CLASS) if you want @BeforeAll inside nested classes.