PowerMockito 在 spring boot 中模拟私有方法
PowerMockito mock private methods in springboot
我正在尝试在我的 class 测试中模拟一个私有方法,如下所示。
public String processPayment(...) {
//some lines
privateMethod(...);
return "";
}
private Object privateMethod(...) {
//some lines
return someObject;
}
现在我需要测试 processPayment
方法和模拟 privateMethod
。
我尝试创建上面的 spy class,但是当我做下面的事情时会调用该方法
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
privateMethod
在第 2 行本身被调用。
此外,the privateMethod
没有被嘲笑。
也许我以错误的方式创建了间谍对象?不能做 spy(new DeviceCheckoutServiceImpl());
因为它需要 bean 实例化。
Powermockito 版本:
compile group: 'org.powermock', name: 'powermock-module-junit4', version: '2.0.0'
compile group: 'org.powermock', name: 'powermock-api-mockito2', version: '2.0.0'
让我知道我做错了什么。
在测试class中我们将通过传递对需要测试的class的引用来调用org.powermock.api.mockito.PowerMockito
的spy()方法:
MockPrivateMethodExample spy = PowerMockito.spy(mockPrivateMethodExample);
然后我们定义当这个特定的私有方法被调用时我们想要做什么。
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);
}
}
Mockito 引入了 AdditionalAnswers.delegatesTo
以支持监视 Spring 代理和其他类似的东西:
检查这个问题:https://github.com/mockito/mockito/issues/529#issuecomment-239494581
So instead of spy(proxy)
use mock(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.
问题已解决!
忘记在测试 class 上添加 @PrepareForTest(DeviceCheckoutServiceImpl.class)
。
我正在尝试在我的 class 测试中模拟一个私有方法,如下所示。
public String processPayment(...) {
//some lines
privateMethod(...);
return "";
}
private Object privateMethod(...) {
//some lines
return someObject;
}
现在我需要测试 processPayment
方法和模拟 privateMethod
。
我尝试创建上面的 spy class,但是当我做下面的事情时会调用该方法
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
privateMethod
在第 2 行本身被调用。
此外,the privateMethod
没有被嘲笑。
也许我以错误的方式创建了间谍对象?不能做 spy(new DeviceCheckoutServiceImpl());
因为它需要 bean 实例化。
Powermockito 版本:
compile group: 'org.powermock', name: 'powermock-module-junit4', version: '2.0.0'
compile group: 'org.powermock', name: 'powermock-api-mockito2', version: '2.0.0'
让我知道我做错了什么。
在测试class中我们将通过传递对需要测试的class的引用来调用org.powermock.api.mockito.PowerMockito
的spy()方法:
MockPrivateMethodExample spy = PowerMockito.spy(mockPrivateMethodExample);
然后我们定义当这个特定的私有方法被调用时我们想要做什么。
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);
}
}
Mockito 引入了 AdditionalAnswers.delegatesTo
以支持监视 Spring 代理和其他类似的东西:
检查这个问题: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.
问题已解决!
忘记在测试 class 上添加 @PrepareForTest(DeviceCheckoutServiceImpl.class)
。