How to test private methods


Recommended Approach: Test via Public Methods

Before diving into hacks, ask yourself:

"Can I validate this private method’s behavior through a public method?"

If yes—do that. It’s cleaner, future-proof, and respects encapsulation.


🛠️ Option 1: Use Reflection (Not Ideal, But Works)

Here’s how you can test private methods using Java reflection:

import org.junit.jupiter.api.Test;

import java.lang.reflect.Method;

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

class MyClass {
    private String greet(String name) {
        return "Hello, " + name;
    }
}

public class MyClassTest {

    @Test
    void testPrivateGreetMethod() throws Exception {
        MyClass obj = new MyClass();
        Method method = MyClass.class.getDeclaredMethod("greet", String.class);
        method.setAccessible(true); // bypass private access

        String result = (String) method.invoke(obj, "John");

        assertEquals("Hello, John", result);
    }
}

⚠️ Caveats

  • Fragile: breaks easily if method signature changes.
  • Ignores encapsulation (anti-pattern).
  • Should be used sparingly—prefer refactoring.

🧪 Option 2: Use Package-Private Access (More Testable Design)

Move your method to package-private (no public/private/protected keyword) instead of private, and put your test class in the same package.

// MyClass.java
class MyClass {
    String internalLogic(String input) {
        return input.trim().toUpperCase();
    }
}

This strikes a balance: still not public, but testable.


🧰 Option 3: Use Testing Libraries (e.g., PowerMock)

Use PowerMock or Mockito with Whitebox to access private methods:

import static org.powermock.reflect.Whitebox.invokeMethod;

@Test
void testPrivateMethodWithPowerMock() throws Exception {
    MyClass obj = new MyClass();
    String result = invokeMethod(obj, "greet", "John");

    assertEquals("Hello, John", result);
}

⚠️ PowerMock is powerful but overkill for most modern Java projects.


✅ Best Practice Summary

ApproachWhen to Use
Test via public method✅ Always preferred
Reflection⚠️ Legacy code or urgent cases
Package-private visibility👍 Clean, testable design
PowerMock / Whitebox⚠️ Last resort for untestable code