Testing Private Method Using Mockito

Testing Private method using mockito

You can't do that with Mockito but you can use Powermock to extend Mockito and mock private methods. Powermock supports Mockito. Here's an example.

How do I TEST (not mock) a private method using Mockito and/or PowerMock?

This is the PowerMockito way.

    @Test
public void testCallPrivateMethod() throws Exception {
Point actual = Whitebox.invokeMethod(powerMockDemo,
"privateMethod", new Point(11, 11));

assertThat(actual.getX(), is(12));
assertThat(actual.getY(), is(12));
}

https://automationrhapsody.com/call-private-method-powermock/

How to mock private method for testing using PowerMock?

I don't see a problem here. With the following code using the Mockito API, I managed to do just that :

public class CodeWithPrivateMethod {

public void meaningfulPublicApi() {
if (doTheGamble("Whatever", 1 << 3)) {
throw new RuntimeException("boom");
}
}

private boolean doTheGamble(String whatever, int binary) {
Random random = new Random(System.nanoTime());
boolean gamble = random.nextBoolean();
return gamble;
}
}

And here's the JUnit test :

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.api.support.membermodification.MemberMatcher.method;

@RunWith(PowerMockRunner.class)
@PrepareForTest(CodeWithPrivateMethod.class)
public class CodeWithPrivateMethodTest {

@Test(expected = RuntimeException.class)
public void when_gambling_is_true_then_always_explode() throws Exception {
CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod());

when(spy, method(CodeWithPrivateMethod.class, "doTheGamble", String.class, int.class))
.withArguments(anyString(), anyInt())
.thenReturn(true);

spy.meaningfulPublicApi();
}
}

Verifying no argument and private methods using Mockito

You could mock scheduleList and orderList instead and use verify to make sure the correct methods are being called from them.

public class MyRuleTest
{
private MyRule myRule;
private ScheduleList scheduleListMock;
private OrderList orderListMock;

@Before
public void setUp() throws Exception
{
scheduleListMock = mock(ScheduleList.class);
orderListMock = mock(OrderList.class);

myRule = new MyRule(orderListMock, scheduleListMock);
}

@Test
public void testExecute()
{
myRule.execute();
verify(scheduleListMock).foo();
verify(orderListMock).bar();
}

...

You would just replace foo and bar with whatever methods you are expecting to be called.

If you are testing MyRule, you shouldn't be mocking it. A good rule of thumb is to not mock the class that is under test.

How to mock private method using powermock?

PowerMock annotations required for mock working:

@RunWith(PowerMockRunner.class)
@PrepareForTest(LuckyNumberGenerator.class)

Example of working test:

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.powermock.api.mockito.PowerMockito.*;

@RunWith(PowerMockRunner.class)
@PrepareForTest(LuckyNumberGenerator.class)
public class ServiceTest {
@Test
public void test() throws Exception {
LuckyNumberGenerator mock = spy(new LuckyNumberGenerator());
PowerMockito.when(mock, "getDefaultLuckyNumber").thenReturn(300);
Assert.assertEquals(300, mock.getLuckyNumber("name"));
}
}

public class LuckyNumberGenerator {
public int getLuckyNumber(String name) {
return getDefaultLuckyNumber();
}
private int getDefaultLuckyNumber() {
return 1;
}
}

PowerMock version:

        <dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>


Related Topics



Leave a reply



Submit