Bird
Raised Fist0
JUnittesting~10 mins

Testing private methods (should you?) in JUnit - Test Execution Trace

Choose your learning style10 modes available
Test Overview

This test checks the behavior of a public method that internally uses a private method. It verifies the final output without directly testing the private method, following best practices.

Test Code - JUnit
JUnit
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;

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

    public int tripleDouble(int x) {
        return doubleValue(x) * 3;
    }
}

public class CalculatorTest {
    @Test
    void testTripleDouble() {
        Calculator calc = new Calculator();
        int result = calc.tripleDouble(4);
        assertEquals(24, result, "tripleDouble should return doubleValue times 3");
    }
}
Execution Trace - 8 Steps
StepActionSystem StateAssertionResult
1Test startsJUnit test runner initialized—PASS
2CalculatorTest creates Calculator instanceCalculator object ready—PASS
3Calls public method tripleDouble(4)Inside Calculator.tripleDouble method—PASS
4tripleDouble calls private method doubleValue(4)Inside Calculator.doubleValue method—PASS
5doubleValue returns 8Back in tripleDouble method—PASS
6tripleDouble returns 8 * 3 = 24Result ready for assertionCheck if result equals 24PASS
7JUnit asserts result == 24Test assertion executedassertEquals(24, result)PASS
8Test ends successfullyTest passed—PASS
Failure Scenario
Failing Condition: The public method tripleDouble returns incorrect value due to private method logic error
Execution Trace Quiz - 3 Questions
Test your understanding
Why does the test call the public method instead of the private method directly?
ABecause public methods are faster to test
BBecause private methods do not contain any logic
CBecause private methods cannot be accessed directly from tests
DBecause the test framework only supports public methods
Key Result
Test the public behavior of a class rather than private methods directly. Private methods are implementation details and should be tested indirectly through public methods.

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