【问题标题】:PowerMockito mock private methods in springbootPowerMockito 在 Spring Boot 中模拟私有方法
【发布时间】: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'

让我知道我在这里做错了什么。

【问题讨论】:

    标签: spring-boot junit mockito powermock powermockito


    【解决方案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)
      猜你喜欢
      • 2015-03-23
      • 2014-09-21
      • 2018-05-03
      • 2018-11-29
      • 1970-01-01
      • 2014-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多