Reputation: 1059
I am trying to mock a private method inside my class under test which is as below.
public String processPayment(...) {
//some lines
privateMethod(...);
return "";
}
private Object privateMethod(...) {
//some lines
return someObject;
}
Now I need to test processPayment
method and mock privateMethod
.
I tried creating spy of the above class, but the method gets called when I do below
final DeviceCheckoutServiceImpl spyDeviceCheckoutService = spy(injectedMockBeanOfAboveClass); //@InjectMock in test class
PowerMockito.doReturn(null).when(spyDeviceCheckoutService, "privateMethod", ArgumentMatchers.anyMap()); //method gets called here
spyDeviceCheckoutService.processPayment(...); //private method isn't mocked somehow, and gets called here too
The privateMethod
gets called on the 2nd line itself.
Also, the privateMethod
isn't mocked.
Maybe I am creating the spy object in a wrong way? Can't do spy(new DeviceCheckoutServiceImpl());
as it needs bean instantiation.
Powermockito version:
compile group: 'org.powermock', name: 'powermock-module-junit4', version: '2.0.0'
compile group: 'org.powermock', name: 'powermock-api-mockito2', version: '2.0.0'
Let me know what I am doing wrong here.
Upvotes: 5
Views: 7625
Reputation: 1059
Issue solved!
Had forgot to add @PrepareForTest(DeviceCheckoutServiceImpl.class)
on the test class.
Upvotes: 4
Reputation: 51451
Mockito introduced AdditionalAnswers.delegatesTo
to support spying on Spring proxies and other such things:
Check out this issue: https://github.com/mockito/mockito/issues/529#issuecomment-239494581
So instead of
spy(proxy)
usemock(TestSubject.class, delegatesTo(springProxy))
.However if annotations are need to read, then you'll need mockito 2 beta. Because mockito 1.x uses CGLIB which doesn't copies annotations on the mockito subclass. Mockito 2 uses the great bytebuddy.
Upvotes: 0
Reputation: 2209
In the test class we will call the spy() method of org.powermock.api.mockito.PowerMockito
by passing the reference to the class that needs to be tested:
MockPrivateMethodExample spy = PowerMockito.spy(mockPrivateMethodExample);
Then we define what we want to do when this particular private method is called.
PowerMockito.doReturn("Test").when(spy, {$methodName});
MockPrivateMethodExample.java
public class MockPrivateMethodExample {
public String getDetails() {
return "Mock private method example: " + iAmPrivate();
}
private String iAmPrivate() {
return new Date().toString();
}
}
MockPrivateMethodTest.java
@RunWith(PowerMockRunner.class)
@PrepareForTest(MockPrivateMethodExample.class)
public class MockPrivateMethodTest {
private MockPrivateMethodExample mockPrivateMethodExample;
// This is the name of the private method which we want to mock
private static final String METHOD = "iAmPrivate";
@Test
public void testPrivateMethod() throws Exception {
mockPrivateMethodExample = new MockPrivateMethodExample();
MockPrivateMethodExample spy = PowerMockito.spy(mockPrivateMethodExample);
PowerMockito.doReturn("Test").when(spy, METHOD);
String value = spy.getDetails();
Assert.assertEquals(value, "Mock private method example: Test");
PowerMockito.verifyPrivate(spy, Mockito.times(1)).invoke(METHOD);
}
}
More details here: https://examples.javacodegeeks.com/core-java/mockito/mockito-mock-private-method-example-with-powermock/
Upvotes: 8