PowerMockito 在 Spring Boot 中模拟私有方法
Posted
技术标签:
【中文标题】PowerMockito 在 Spring Boot 中模拟私有方法【英文标题】:PowerMockito mock private methods in springboot 【发布时间】:2019-09-06 11:53:06 【问题描述】:我正在尝试在我的测试类中模拟一个私有方法,如下所示。
public String processPayment(...)
//some lines
privateMethod(...);
return "";
private Object privateMethod(...)
//some lines
return someObject;
现在我需要测试processPayment
方法并模拟privateMethod
。
我尝试创建上述类的 spy,但是当我在下面进行时,该方法被调用
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
在第二行本身被调用。
此外,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'
让我知道我在这里做错了什么。
【问题讨论】:
【参考方案1】:在测试类中,我们将调用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);
更多详情:https://examples.javacodegeeks.com/core-java/mockito/mockito-mock-private-method-example-with-powermock/
【讨论】:
已经试过了。每当我执行PowerMockito.doReturn("Test").when(spy, METHOD);
时,都会调用该方法,此外,该方法不会被嘲笑。 :-/
@PraveenKamath 您能否将答案标记为有用。谢谢。【参考方案2】:
问题解决了!
忘记在测试类中添加@PrepareForTest(DeviceCheckoutServiceImpl.class)
。
【讨论】:
【参考方案3】:Mockito 引入了AdditionalAnswers.delegatesTo
来支持对 Spring 代理和其他类似事物的监视:
查看这个问题:https://github.com/mockito/mockito/issues/529#issuecomment-239494581
所以不要使用
spy(proxy)
,而是使用mock(TestSubject.class, delegatesTo(springProxy))
。但是,如果需要阅读注释,则需要 mockito 2 贝塔。因为 mockito 1.x 使用不复制注释的 CGLIB 在 mockito 子类上。 Mockito 2 使用了伟大的 bytebuddy。
【讨论】:
发现问题。没有在测试类中添加@PrepareForTest(DeviceCheckoutServiceImpl.class)
。以上是关于PowerMockito 在 Spring Boot 中模拟私有方法的主要内容,如果未能解决你的问题,请参考以下文章
spring-boot实战05:Spring Boo多环境配置及配置属性注入到对象
spring boo的简单搭建(eclipse+springboot + redis + mysql + thymeleaf)