1

The test for the public method getA() works as expected, but the test for the private method getB() does not return the mocked value "b", but "B", which corresponds to the actual return value of the method getB(). How must the test to getB() be adjusted so that the mocked value "b" is returned?

public class Letters {
    public String getA() {
        return "A";
    }

    private String getB() {
        return "B";
    }
}
class LettersTest {
    Letters mockedLetters = mock(Letters.class);

    @Test
    void getA() {
        when(mockedLetters.getA()).thenReturn("a");
        assertThat(mockedLetters.getA()).isEqualTo("a"); // True.

        // To check if ReflectionTestUtils actually sets the value in mockedLetters.
        when(ReflectionTestUtils.invokeMethod(mockedLetters, "getA")).thenReturn("aa");
        assertThat(mockedLetters.getA()).isEqualTo("aa"); // True.
    }

    @Test
    void getB() {
        when(ReflectionTestUtils.invokeMethod(mockedLetters, "getB")).thenReturn("b");
        assertThat((String)ReflectionTestUtils.invokeMethod(mockedLetters, "getB")).isEqualTo("b"); // False; expected: "b", but was: "B".
    }
}
Anne Maier
  • 299
  • 1
  • 8
  • Frame challenge: should you be testing private methods at all? These are, by definition, implementation details of your class. – John Bollinger May 01 '22 at 13:56

1 Answers1

0

You can do:

  1. Using PowerMockito
  2. Using Reflection to change your private method to public one for test and change it back.

But... wait... Don't ever do any of above things. Because:

  1. You need to design your code to be testable.
  2. Private methods should be tested through the public ones. Read more about TDD.

Some references I can see for you:

you shouldn't test private methods directly, but only their effects on the public methods that call them

  • Note that Spring's `ReflectionUtils`, which I'm guessing is the one the OP is using, claims to be able to invoke private methods. I take the question as posed to be asking why that's not working as expected. However, I quite agree about not testing private methods directly. – John Bollinger May 01 '22 at 14:02
  • Thanks. I can see that he's using reflection, which is (2) from my point. But that's why I'm trying to tell: do not test private methods. –  May 01 '22 at 14:02
  • Which is well and good, but what I'm saying is *that this does not answer the question posed*. – John Bollinger May 01 '22 at 14:03
  • It does not answer the question directly, but it answered the question indirectly which will lead to a better code. –  May 01 '22 at 14:04