看起来正确的doThrow中的Mockito异常

时间:2012-08-29 22:15:04

标签: java mockito

我正在尝试模拟一个方法来查看我是否正确处理了异常。这是我得到的。

接口:

interface SampleManager {
    void deleteVariome(String specimenId, String analysisId) throws Exception;
    // ...
}

单元测试:

// ...
SampleManger sampleManager = mock(SampleManager.class);

// below is line 753
doThrow(Exception.class).when(sampleManager).deleteVariome(sample1.getId(), analysisId);

结果:

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at ...server.ArchiveManagerImplUTest.deleteVariomeFails(ArchiveManagerImplUTest.java:753)

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(); <-- this looks a log like what I did!

Hints:

 1. missing thenReturn()

 2. you are trying to stub a final method, you naughty developer! <-- I have a lot of other mocks of this interface in this test that work.

5 个答案:

答案 0 :(得分:19)

从我遇到的一个相同的问题,我怀疑sample是一个模拟,你在其他地方存在sample.getId()?无论如何,这在我的案例中引起了这个问题。

出于某种原因,如果以这种方式传递给与doThrow一起使用的存根的其中一个参数是您也嘲笑的方法的结果,Mockito会感到沮丧。也许这是一种重新进行的检查,以避免无限循环,我不知道。

无论如何,尝试用常量值替换sample.getId(),这应该可以解决问题。你可以考虑在你的测试中使用一个常量来模拟它和它的任何进一步用途。然后,您还可以通过添加对sample.getId()的另一个调用来检查您正在测试的方法是否使用了verify

答案 1 :(得分:4)

此错误通常在实际发生的地方后报告。如果你没有正确地存根,Mockito通常无法分辨,直到你下一次调用Mockito方法之一。这可能是在同一个测试方法中,同一个类中的后续测试方法,甚至是完全不同的测试类。

你引用的那条线对我来说很好看。看看它上面的线条,你可以称之为Mockito存根或验证方法。很可能您的when没有关联thenReturnthenthenThrow。或者您可能有verify缺少实际的方法调用。还有其他一些可能性。

如果您在引用的行中找不到错误,请发布更多代码,我会仔细查看。

答案 2 :(得分:4)

正如Gijs的回答所述,这可能是由于Mockito的一个错误。这是一个完整的测试,可以重现它:

interface Sample { String getId(); }
interface SampleManager {
    void deleteVariome(String specimenId, String analysisId);
}

@Test
public void probableMockitoBug() {
    Sample sample1 = mock(Sample.class);
    when(sample1.getId()).thenReturn("a");

    SampleManager manager = mock(SampleManager.class);
    doThrow(Exception.class).when(manager).deleteVariome(sample1.getId(), "b");

    manager.deleteVariome("a", "b");
}

测试产生以下输出:

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at org.mockitousage.JavadocExamplesTest.probableMockitoBug(JavadocExamplesTest.java:404)

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!

    at org.mockito.exceptions.Reporter.unfinishedStubbing(Reporter.java:55)
    at org.mockito.internal.progress.MockingProgressImpl.validateState(MockingProgressImpl.java:74)
    at org.mockito.internal.progress.ThreadSafeMockingProgress.validateState(ThreadSafeMockingProgress.java:49)
    at org.mockito.internal.MockHandler.handle(MockHandler.java:71)
    at org.mockito.internal.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:36)
    at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:48)
    at org.mockitousage.JavadocExamplesTest$Sample$$EnhancerByMockitoWithCGLIB$$d5ac41.getId()
    at org.mockitousage.JavadocExamplesTest.probableMockitoBug(JavadocExamplesTest.java:404)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)

答案 3 :(得分:0)

你必须提供Exception.class的实例而不是Exception类本身。

doThrow(new Exception()).when(sampleManager).deleteVariome(sample1.getId(), analysisId);

修改 好吧@DavidWallace纠正了我,所以要警告(或者说更开明),因为1.9你可以提供抛出的异常类,它将为你构建一个。

答案 4 :(得分:0)

在我的情况下,而不是

doThrow(exception).when(mock).someVoidMethod()

doThrow(exception).when(mock.someVoidMethod())