Mockito拒绝抛出checked异常

yyyllmsg  于 2023-10-18  发布在  其他
关注(0)|答案(5)|浏览(124)

我正在使用Mockito进行单元测试,我遇到了一个在spied对象上抛出异常的问题。我以前在这个对象上做过这个(在不同的测试用例中,它工作了)。下面是测试代码:

@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)

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

8ehkhllq

8ehkhllq1#

我终于找到了解决这个问题的办法。
我们使用了一个匿名类来扩展原始的Sbb类,这个类已经过测试,在这个扩展的类中,提到的方法的实现被改变了,throws表达式被删除了,这导致了这个问题。
我应该更仔细地阅读我同事的代码。

chhkpiq4

chhkpiq42#

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

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

我知道这已经太晚了,但以防万一有人面临同样的问题。

kb5ga3dv

kb5ga3dv3#

我觉得解决方案是使用doThrow()语法而不是when().thenThrow()。当进行间谍活动时,使用doThrow/doReturn语法进行拦截更安全。其原因在文档中有所描述:http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#13
我认为我们可以改进这种情况下的异常消息,

camsedfj

camsedfj4#

我知道这篇文章很老了,但我的解决方案可能对某人有帮助:我通过将方法的可见性改为public来解决这个错误。
在这种情况下你应该有零钱

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

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

dxpyg8gm5#

在我的例子中,由于我在void方法上使用了@SneakyThrows,我必须在mock中抛出RuntimeException,而不是普通的异常,所以

doThrow(new RuntimeException()).when(mock).doStuff(any());

相关问题