【问题标题】:Mockito refuses to throw checked exceptionMockito 拒绝抛出检查异常
【发布时间】:2011-07-11 09:10:06
【问题描述】:

我正在使用 Mockito 进行单元测试,但遇到了在间谍对象上抛出异常的问题。我之前在这个对象上做过这个(在不同的测试用例中并且它有效)。 下面是测试代码:

@Test
public void callInitiated_FsmInitializationException() throws FsmInitializationException, Exception {
    MocSbb moc = Mockito.spy(testObj);

    MocTracer tracer = Mockito.mock(MocTracer.class);
    Mockito.doReturn(tracer).when(moc).getTracer();

    CAP2InitialDPArg idp = Mockito.mock(CAP2InitialDPArg.class);
    MocFsm mocFsm = Mockito.mock(MocFsm.class);
    //Mockito.doReturn(mocFsm).when(moc).getSs7Fsm();

    TicketingLocalInterface ticketing = mockTicketingLocalInterface();
    CAP2InitialDPArgWrap idpWrap = Mockito.mock(CAP2InitialDPArgWrap.class);
    PowerMockito.whenNew(CAP2InitialDPArgWrap.class).withArguments(idp, tracer).thenReturn(idpWrap);

    MocSession mocSession = Mockito.mock(MocSession.class);
    Mockito.doReturn(mocSession).when(moc).getMocSession();

    Mockito.when(moc.getSs7Fsm()).thenThrow(new FsmInitializationException()); ////HERE'S THE PROBLEM

    moc.callInitiated(idp);

    verify(moc).getFailedFsm();
} 

这是应该抛出异常的方法:

protected MocFsm getSs7Fsm() throws FsmInitializationException {
    mocFsm.setContextProvider(getMocLocalObject());
    return mocFsm;
}  

我在测试执行期间遇到的错误如下所示:

Testcase: callInitiated_FsmInitializationException(com.nsn.as.ccs.moc.sbb.MocSbbTest):  Caused an ERROR

Checked exception is invalid for this method!
Invalid: com.nsn.as.ccs.moc.fsm.FsmInitializationException
org.mockito.exceptions.base.MockitoException: 
Checked exception is invalid for this method!
Invalid: com.nsn.as.ccs.moc.fsm.FsmInitializationException
at com.nsn.as.ccs.moc.sbb.MocSbbTest.callInitiated_FsmInitializationException(MocSbbTest.java:1194)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:322)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:309)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:112)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:73)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:297)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:222)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:161)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:135)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:133)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:112)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:57)  

有谁知道为什么它在这种情况下不起作用?

【问题讨论】:

  • 不是重复的,而是关于该主题的另一个问题:stackoverflow.com/questions/3762047/…
  • 我已经看到了,但它没有回答我的问题。不过谢谢
  • testObj的类型是什么?是MocSbb 还是超类或接口?接口/父类是否也声明异常?

标签: java exception junit mockito


【解决方案1】:

关注this answer。使用 Mockito 的 doAnswer 而不是 thenThrow 方法解决了我的问题。

Mockito.doAnswer(
      invocation -> {
        throw new Exception("Something went wrong");
      })
  .when(moc)
  .getSs7Fsm();

我知道为时已晚,但以防万一有人遇到同样的问题。

【讨论】:

    【解决方案2】:

    我终于找到了解决这个问题的方法。

    我们使用了一个匿名类扩展原始 Sbb 类,该类经过测试,在这个扩展类中,上述方法的实现被改变,throws 表达式被删除,导致问题。

    我应该更仔细地阅读我同事的代码。

    【讨论】:

    • 我也遇到过这种情况,但是有一个实现接口的类
    【解决方案3】:

    我感觉解决方案是使用 doThrow() 语法而不是 when().thenThrow()。在进行间谍活动时,使用 doThrow/doReturn 语法进行存根会更安全。原因在文档中有所描述:http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#13

    我认为我们可以在这种情况下改进异常消息,使其成为 m

    【讨论】:

    • 原因:存根 void 需要与 Mockito.when(Object) 不同的方法,因为编译器不喜欢括号内的 void 方法...
    • 这对我不起作用。最终起作用的实际上是将异常更改为 RuntimeException 类型。我不清楚为什么 Mockito 不允许使用这些方法抛出已检查的异常。
    【解决方案4】:

    我知道这篇文章很旧,但我的解决方案可能对某人有所帮助: 我通过将要测试的方法的可见性更改为公开来解决了同样的错误。

    在这种情况下,你应该有变化

    protected MocFsm getSs7Fsm() throws FsmInitializationException {
        ...
    }
    

    public MocFsm getSs7Fsm() throws FsmInitializationException {
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 2012-09-11
      • 2014-04-06
      • 2013-05-24
      • 1970-01-01
      • 2015-10-11
      • 1970-01-01
      • 2011-04-15
      • 1970-01-01
      • 2020-10-28
      相关资源
      最近更新 更多