【问题标题】:Unfinished stubbing Exception when using PowerMockito & Mockito使用 PowerMockito 和 Mockito 时未完成的存根异常
【发布时间】:2017-03-10 19:14:06
【问题描述】:

我正在尝试使用 PowerMockito 和 Mockito,如下所示:

@RunWith(PowerMockRunner.class)
@PrepareForTest({AmqpMessagePublisher.class})
public class OrderItemManagerImplTest {

 @Spy
 @InjectMocks
 private OrderItemManager orderItemManager = new OrderItemManagerImpl();

 @Mock
 private OrderReleaseManager srReleaseManager;

 @Spy
 private srOrderTransformer srOrderTransformer;

 private OrderItemEntry getOrderItemEntry() {
  OrderItemEntry orderItemEntry = new OrderItemEntry();
  orderItemEntry.setProcessingStartDate("2017-03-01");
  return orderItemEntry;
 }

 @Before
 public void setUp() throws Exception {
  MockitoAnnotations.initMocks(this);
  PowerMockito.mockStatic(AmqpMessagePublisher.class);
  PowerMockito.doNothing().when(AmqpMessagePublisher.class);
 }

 @Test
 public void testCreateOrder() throws Exception {
  OrderItemEntry expected = getOrderItemEntry();
  String expectedItemId = expected.getItems().get(0).getItemId(); 
  // the below line is throwing the exception      
  Mockito.when(srReleaseManager.getReleaseByStoreReleaseId(expectedItemId)).thenReturn(null); 
 }
}

在尝试测试上面的代码时抛出异常

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at org.powermock.api.mockito.internal.PowerMockitoCore.doAnswer(PowerMockitoCore.java:36)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, you naughty developer!
 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed

    at com.myntra.sr.manager.impl.jb.OrderItemManagerImplTest.testCreateOrder(OrderItemManagerImplTest.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:94)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106)
    at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
    at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

我已经解决了this 问题和this 问题。但他们都没有帮助。有人可以告诉我我做错了什么吗?

【问题讨论】:

    标签: java mocking mockito powermockito


    【解决方案1】:

    你必须在模拟后调用静态方法。请参见下面的示例。

    PowerMockito.doNothing().when(StaticService.class);
    StaticService.executeMethod();
    

    参考:https://github.com/powermock/powermock/wiki/MockitoUsage#how-to-stub-void-static-method-to-throw-exception

    编辑:

    所以我应该移动 PowerMockito.doNothing().when(AmqpMessagePublisher.class);在 testSetup 中的 testCreateOrder 中并调用调用 AmqpMessagePublisher 的方法?

    你可以把它留在原处。问题是这样的。当你模拟一个 void 静态方法时,PowerMocks API 中的事情会变得有点棘手。传统的doNothing().when(someObject).mockedMethod(); 不起作用。他们解决这个问题的方式有点奇怪。他们希望您在 doNothing().when(AmqpMessagePublisher.class) 行之后调用被模拟的实际静态 void 方法。这告诉 PowerMock 从 AmqpMessagePublisher 模拟哪个静态方法。例如,假设您在 AmqpMessagePublisher 中有 10 个静态 void 方法,doNothing() 不会传达要模拟的方法。但是下一条直接线可以。

    【讨论】:

    • 我做对了。在setUp(),我已经打电话给PowerMockito.mockStatic(AmqpMessagePublisher.class)
    • 是的,然后调用该方法。
    • 该方法在testCreateOrder 中被调用。在setUp 中,我已致电mockStatic。所以无论如何我已经按照你的建议去做了。
    • 你不明白,你必须在 doNothing 行之后调用你想模拟的方法。在您的代码中,您没有按照我的建议执行文章。
    • 是的,它有帮助。谢谢。确实有点奇怪。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 2020-09-07
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 2021-02-01
    相关资源
    最近更新 更多