0

If I am writing unit test for a Singleton class then how can I go about mocking the private method of the Singleton class. A sample code snippet for the scenario I am looking for is below :-

Class Singleton {
   private static Singleton instance = new Singleton();

   protected Singleton() {}
   public Singleton synchronized getInstance() { return instance;}

   public int method1(int a) {
       int ret = method2(a);
       return ret;
   }

   private int method2(int num) { return num + 1;}
}

How can I mock method2 in order to test method1 in the above example ?

Siddharth
  • 2,046
  • 5
  • 26
  • 41
  • 1
    Why do you need to mock method2 in order to test method1? – clD Sep 29 '14 at 11:41
  • I am new to Unit Testing. I thought that in order to test method1 I will have to create a dummy method2 so that no call to the actual method2 happens. If my approach is incorrect, kindly tell me how should I go about unit testing method1 ? – Siddharth Sep 29 '14 at 14:39

1 Answers1

1

To test method1 you just need to test it like any other method. The Object under test in this case the Singleton class should not be mocked.

Create a test object i.e. your class under test (testee) usually in a setup method then:

@Test
public void testMethod1() {
    int testValue = 1;      
    int expectedResult = 2;

    assertThat(testee.method1(testValue), equalTo(expectedResult));
}

In the example above I would use parametrized testing with something like JUnitParams to test boundaries for example, Integer MAX_VALUE etc.

@Test
@Parameters(method = "method1Params")
public void testMethod1(int testValue, int expectedResult) {
    assertThat(testee.method1(testValue), equalTo(expectedResult));
}

@Ignore
private final Object[] method1Params() {
    return new Object[] {
        new Object { 1, 2 },
        new Object { -2, -1 }
    };
}

Mocking is mainly used when you want to test the SUT, in this case the Singleton in isolation from other components (collaborators) to ensure it behaves correctly. In this case it is not necessary.

When you could use a mock

public int method1(DependedOnComponent doc) {
    int a = 1;

    int ret = doc.method2(a);

    return ret;
}

then

@Test
public void testMethod1() {
    DependedOnComponent mockDOC = mock(DependedOnComponent.class);

    // When method2() is called you control the value returned
    when(mockDOC.method2(1)).thenReturn(2);

    assertThat(testee.method1(mockDOC), equalTo(2));
}
clD
  • 2,523
  • 2
  • 22
  • 38
  • Thanks for your answer. So, do I consider that it is expected that the test to a method (here method1) can make a call to other private methods (here method2) of the same class. I am saying this because "assertThat(testee.method1(testValue), equalTo(expectedResult));" will make an actual call to method2 also. – Siddharth Sep 30 '14 at 06:11
  • Yes, it is not recommended to mock private methods. Also `method1` calling `method2` allows you to test the behaviour of the private method. Although a matter of opinion in most circumstances private methods are not tested directly but tested through the public API. There is a good discussion on testing private methods here. http://stackoverflow.com/questions/105007/should-i-test-private-methods-or-only-public-ones – clD Sep 30 '14 at 08:13
  • I just want to add it is possible to mock private methods using PowerMock using partial mocking with spy etc [example powermock site](https://code.google.com/p/powermock/wiki/MockitoUsage13) and [example](http://stackoverflow.com/questions/9719919/is-it-possible-to-use-partial-mocking-for-private-static-methods-in-powermock) but it is not recommended and not necessary in the scenario above. – clD Sep 30 '14 at 10:05