Introduction
In this chapter, we will explore JUnit nested tests. Nested tests allow you to logically group test classes within a single test class. This is useful for organizing tests that share a common context or setup, making your test suite easier to maintain and understand.
What are Nested Tests?
Nested tests are a way to structure your tests hierarchically by nesting test classes within each other. This helps in grouping related tests together and setting up shared context more effectively. JUnit 5 provides the @Nested annotation to create nested test classes.
Overview of @Nested Annotation
The @Nested annotation is used to define a nested test class. This annotation indicates that the enclosed class is a nested, non-static test class, which can contain its own lifecycle methods and test methods. Nested tests can help to:
- Organize tests that share a common setup.
- Group related tests logically.
- Provide a clear structure for complex test scenarios.
Example: Creating Nested Tests
Let’s create nested tests for a simple Account class to demonstrate how nested tests can be used to organize tests.
Step 1: Create Class Under Test
Account Class
The Account class will have methods for deposit, withdrawal, and checking the balance.
public class Account {
private double balance;
public Account(double initialBalance) {
if (initialBalance < 0) {
throw new IllegalArgumentException("Initial balance cannot be negative");
}
this.balance = initialBalance;
}
public void deposit(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("Deposit amount must be positive");
}
balance += amount;
}
public void withdraw(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("Withdrawal amount must be positive");
}
if (amount > balance) {
throw new IllegalArgumentException("Insufficient funds");
}
balance -= amount;
}
public double getBalance() {
return balance;
}
}
Step 2: Create Nested Test Class
AccountTest
The AccountTest class will contain nested test classes to group tests logically.
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class AccountTest {
private Account account;
@Nested
class WhenNew {
@BeforeEach
void setUp() {
account = new Account(100.0);
}
@Test
void initialBalanceIsSet() {
assertEquals(100.0, account.getBalance());
}
@Test
void depositIncreasesBalance() {
account.deposit(50.0);
assertEquals(150.0, account.getBalance());
}
@Test
void withdrawalDecreasesBalance() {
account.withdraw(50.0);
assertEquals(50.0, account.getBalance());
}
@Test
void withdrawalWithInsufficientFundsThrowsException() {
Exception exception = assertThrows(IllegalArgumentException.class, () -> {
account.withdraw(150.0);
});
assertEquals("Insufficient funds", exception.getMessage());
}
}
@Nested
class WhenOverdrawn {
@BeforeEach
void setUp() {
account = new Account(50.0);
account.withdraw(50.0);
}
@Test
void balanceIsZero() {
assertEquals(0.0, account.getBalance());
}
@Test
void depositIncreasesBalance() {
account.deposit(50.0);
assertEquals(50.0, account.getBalance());
}
@Test
void withdrawalThrowsException() {
Exception exception = assertThrows(IllegalArgumentException.class, () -> {
account.withdraw(10.0);
});
assertEquals("Insufficient funds", exception.getMessage());
}
}
}
Important Points
Explanation of the Nested Test Class
- @Nested: This annotation marks the enclosed class as a nested, non-static test class.
- @BeforeEach: This annotation marks a method to be run before each test method in the enclosing class. It is used here to set up a common
Accountinstance for all nested tests. - WhenNew, WhenOverdrawn: These are nested test classes that group related tests together.
Running the Nested Tests using IntelliJ IDEA
To run the nested tests, simply run the AccountTest class as a JUnit test. This will execute all the test methods in the nested test classes.
- Run Nested Tests: Click the green run icon next to the
AccountTestclass and selectRun. - View Results: The results will be displayed in the Run window. A green check mark indicates that all tests passed, while a red cross indicates that some tests failed.

Conclusion
JUnit nested tests are a powerful way to organize and manage your tests. By grouping related test classes within a single test class, you can run all relevant tests together and get a comprehensive view of your test results. Nested tests help you maintain a clear structure for complex test scenarios, making it easier to manage large test sets in your Java projects.