Bird
Raised Fist0
JUnittesting~15 mins

Testing private methods (should you?) in JUnit - Build an Automation Script

Choose your learning style10 modes available
Verify behavior of a public method that uses a private method internally
Preconditions (1)
Step 1: Create an instance of the class
Step 2: Call the public method with a specific input
Step 3: Observe the output or behavior influenced by the private method
✅ Expected Result: The public method returns the expected result that depends on the private method's logic
Automation Requirements - JUnit 5
Assertions Needed:
Assert the public method returns the expected value influenced by the private method
Best Practices:
Test only public methods, not private methods directly
Use assertions to verify outputs or side effects
Avoid reflection or changing access modifiers to test private methods
Automated Solution
JUnit
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;

class Calculator {
    private int multiplyByTwo(int number) {
        return number * 2;
    }

    public int doubleAndAddThree(int number) {
        return multiplyByTwo(number) + 3;
    }
}

public class CalculatorTest {

    @Test
    void testDoubleAndAddThree() {
        Calculator calculator = new Calculator();
        int input = 5;
        int expected = 13; // (5 * 2) + 3 = 13
        int actual = calculator.doubleAndAddThree(input);
        assertEquals(expected, actual, "The public method should return correct result based on private method logic");
    }
}

This test class CalculatorTest tests the public method doubleAndAddThree of the Calculator class.

The private method multiplyByTwo is not tested directly. Instead, we verify the public method's output, which depends on the private method.

This approach follows best practices by testing behavior through public interfaces, avoiding fragile tests that depend on private implementation details.

Common Mistakes - 3 Pitfalls
Trying to test private methods directly using reflection
Changing private methods to public just to test them
Not asserting expected results and only calling methods
Bonus Challenge

Now add tests for the public method with multiple input values using parameterized tests

Show Hint

Practice

(1/5)
1. Why is it generally discouraged to write JUnit tests that directly test private methods?
easy
A. Because private methods cannot be accessed by JUnit at all.
B. Because private methods are implementation details and should be tested indirectly through public methods.
C. Because testing private methods requires special annotations that are not supported.
D. Because private methods always contain trivial code that doesn't need testing.

Solution

  1. Step 1: Understand the role of private methods in design

    Private methods are internal helpers meant to support public methods and are not part of the class's external behavior.
  2. Step 2: Consider testing best practices

    Tests should focus on the behavior exposed by public methods, ensuring private methods work correctly as part of that behavior.
  3. Final Answer:

    Because private methods are implementation details and should be tested indirectly through public methods. -> Option B
  4. Quick Check:

    Test behavior, not private code [OK]
Hint: Test public methods to cover private ones indirectly [OK]
Common Mistakes:
  • Trying to access private methods directly with reflection
  • Assuming private methods don't need testing at all
  • Confusing private with protected or public methods
2. Which of the following is a correct way to test private methods in JUnit without changing their access modifier?
easy
A. Use reflection to invoke the private method directly in the test.
B. Change the private method to public and test it directly.
C. Test the private method indirectly by calling the public method that uses it.
D. Use a special JUnit annotation @TestPrivate to test private methods.

Solution

  1. Step 1: Review JUnit capabilities

    JUnit does not provide a built-in annotation to test private methods directly.
  2. Step 2: Identify best practice

    Testing private methods indirectly through public methods is the recommended approach without changing access modifiers or using reflection.
  3. Final Answer:

    Test the private method indirectly by calling the public method that uses it. -> Option C
  4. Quick Check:

    Test via public interface [OK]
Hint: Test private logic through public methods only [OK]
Common Mistakes:
  • Using reflection unnecessarily
  • Changing method visibility just for testing
  • Expecting JUnit to support private method testing directly
3. Consider the following Java class snippet:
public class Calculator {
    private int multiply(int a, int b) {
        return a * b;
    }
    public int square(int x) {
        return multiply(x, x);
    }
}

Which JUnit test will correctly verify the multiply method's behavior without accessing it directly?
medium
A. Assert.assertEquals(6, new Calculator().square(2));
B. Assert.assertEquals(9, new Calculator().multiply(3, 3));
C. Assert.assertEquals(6, new Calculator().multiply(2, 3));
D. Assert.assertEquals(9, new Calculator().square(3));

Solution

  1. Step 1: Identify accessible methods

    The multiply method is private and cannot be called directly in tests.
  2. Step 2: Use public method that calls private method

    The square method calls multiply internally, so testing square indirectly tests multiply.
  3. Final Answer:

    Assert.assertEquals(9, new Calculator().square(3)); -> Option D
  4. Quick Check:

    Test private via public method [OK]
Hint: Test private logic by calling public methods that use it [OK]
Common Mistakes:
  • Trying to call private method directly in test
  • Confusing expected results for square vs multiply
  • Using wrong assertion values
4. You have the following test code trying to test a private method using reflection:
Method method = Calculator.class.getDeclaredMethod("multiply", int.class, int.class);
method.setAccessible(true);
int result = (int) method.invoke(new Calculator(), 2, 3);
Assert.assertEquals(6, result);

What is a potential problem with this approach?
medium
A. Reflection breaks encapsulation and makes tests fragile to implementation changes.
B. The method.invoke call will always throw an exception for private methods.
C. JUnit does not support assertions on reflection results.
D. Private methods cannot be found by getDeclaredMethod.

Solution

  1. Step 1: Understand reflection usage

    Reflection can access private methods but bypasses normal access control, breaking encapsulation.
  2. Step 2: Consider test maintenance impact

    Tests using reflection are fragile because private method signatures or logic changes can break tests even if public behavior is unchanged.
  3. Final Answer:

    Reflection breaks encapsulation and makes tests fragile to implementation changes. -> Option A
  4. Quick Check:

    Reflection risks fragile tests [OK]
Hint: Avoid reflection; test behavior via public methods [OK]
Common Mistakes:
  • Assuming reflection is always safe for testing
  • Believing private methods cannot be accessed by reflection
  • Ignoring test maintenance costs
5. You have a class with complex private methods that are hard to test indirectly. What is the best approach to make testing easier while following good design and testing principles?
hard
A. Refactor the complex private methods into a new public helper class and test that class directly.
B. Make all private methods public temporarily during testing and revert after tests.
C. Use reflection to test private methods directly in all test cases.
D. Ignore testing private methods since they are internal and assume they work.

Solution

  1. Step 1: Identify testing challenges with complex private methods

    Complex private methods can be difficult to test indirectly and may indicate design issues.
  2. Step 2: Apply refactoring for better testability

    Extracting complex logic into a new public helper class allows direct testing and improves code clarity.
  3. Final Answer:

    Refactor the complex private methods into a new public helper class and test that class directly. -> Option A
  4. Quick Check:

    Refactor for testable public classes [OK]
Hint: Extract complex logic to public classes for easier testing [OK]
Common Mistakes:
  • Changing access modifiers just for tests
  • Overusing reflection for private method testing
  • Skipping tests for complex private logic
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard