0
0
JUnittesting~5 mins

Testing private methods (should you?) in JUnit

Choose your learning style9 modes available
Introduction

Private methods are hidden helpers inside a class. Testing them directly can make tests fragile. Instead, test the public behavior that uses them.

When you want to ensure the main features of your class work correctly.
When private methods are complex but only used internally.
When you want to avoid breaking tests if internal code changes but behavior stays the same.
When you want to keep tests simple and focused on what users see.
When refactoring code and you want to keep tests stable.
Syntax
JUnit
public class MyClass {
    private int helper(int x) {
        return x * 2;
    }

    public int calculate(int y) {
        return helper(y) + 1;
    }
}

Private methods cannot be called directly from test classes.

Test the public methods that use private methods instead.

Examples
Private method doubleValue is used inside public method addOneAfterDouble.
JUnit
public class Calculator {
    private int doubleValue(int x) {
        return x * 2;
    }

    public int addOneAfterDouble(int x) {
        return doubleValue(x) + 1;
    }
}
Test calls only the public method addOneAfterDouble. Private method is tested indirectly.
JUnit
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

public class CalculatorTest {
    @Test
    void testAddOneAfterDouble() {
        Calculator calc = new Calculator();
        assertEquals(5, calc.addOneAfterDouble(2));
    }
}
Sample Program

This test checks the public method addOneAfterDouble. It indirectly tests the private method doubleValue by verifying the final result.

JUnit
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

public class Calculator {
    private int doubleValue(int x) {
        return x * 2;
    }

    public int addOneAfterDouble(int x) {
        return doubleValue(x) + 1;
    }
}

class CalculatorTest {
    @Test
    void testAddOneAfterDouble() {
        Calculator calc = new Calculator();
        assertEquals(5, calc.addOneAfterDouble(2));
        assertEquals(11, calc.addOneAfterDouble(5));
    }
}
OutputSuccess
Important Notes

Testing private methods directly can make tests fragile and tightly coupled to implementation.

If a private method is very complex, consider refactoring it into a separate class with public methods.

Use reflection to test private methods only as a last resort, because it breaks encapsulation.

Summary

Test private methods indirectly through public methods.

Keep tests focused on behavior, not implementation details.

Refactor complex private logic into testable public classes if needed.