Explain Codes LogoExplain Codes Logo

How do I test a class that has private methods, fields or inner classes?

java
test-engineering
best-practices
reflection
Alex KataevbyAlex Kataev·Feb 13, 2025
TLDR

Test private elements in Java using:

  1. Refactoring to public or package-private for testability.
  2. Reflection to bypass access control:
Method method = MyClass.class.getDeclaredMethod("privateMethod"); method.setAccessible(true); Object result = method.invoke(new MyClass());
  1. Frameworks like JUnit and @Testable for private testing.

Remember, refactoring is ideal to maintain design and encapsulation. Use reflection as a last resort.

Digging deeper

When it comes to testing private methods, fields, or inner classes, the following methods can help:

Eyes on the Coverage

Use code coverage tools like Cobertura to get an overview of private methods testing.

Spaghetti Code or Lasagna Code?

If private methods include significant logic or essential algorithms, refactor to a public class or a companion class. Think of it as preferring lasagna (layered) over spaghetti (tangled)!

All in the family

When testing private inner classes, consider using nested classes in your tests. This way, the test class structure mimics the subject's structure, creating a closely-knit family of tests.

Right under your nose

Sometimes, the best hiding place is in plain sight. Make a private method package-private and it remains hidden from the consumer while your test classes can access it.

Reflections: Not just for Philosophers

In case of no other alternative, use reflection. It's the programming equivalent of pulling a rabbit out of a hat. To streamline this magic trick, create helper methods.

The Crystal Ball

Take the necessity of testing private methods as a sign to reflect on your class design. Think about the trade-offs between encapsulation and testability.

More tools in the toolbox

PowerMock and the Unmovable Boulder

When it’s easier to move a mountain than modify a static final field, PowerMock is your friend. Your tool to make the immovable, movable.

Never Underestimate the Power of Persuasion

Use mocking to verify private method interactions. Mocking is the perfect chameleon, it adapts to the situation and behaves just the way you need it to.

Encapsulation vs. Breaking In

Weigh between encapsulation principle and testing needs. Becoming a coding cat burglar solely for testing is not recommended.

Resilient code: More important than a Pass on Tests

Tests that withstand refactoring are the real winners! They affirm the code's behaviour, not its quirks. Code integrity trumps everything else.

The More You Know

Be adaptable and willing to update your testing strategies. The world is dynamic and so is the practice of testing private methods.