22

我正在尝试模拟一种方法,看看我是否正确处理了异常。这是据我所知。

界面:

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.
4

4 回答 4

20

从我刚刚遇到的一个相同问题中,我怀疑这sample是一个模拟,你sample.getId()在其他地方存根吗?无论如何,这在我的情况下导致了这个问题。

出于某种原因,如果您传递给以这种方式使用的存根的参数之一是您也模拟的方法的结果,则 Mockito 会感到不安doThrow。也许这是一种避免无限循环的重入检查,我不知道。

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

于 2012-09-03T09:42:14.427 回答
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:
此处检测到未完成的存根:
-> 在 org.mockitousage.JavadocExamplesTest.probableMockitoBug(JavadocExamplesTest.java:404)

例如 thenReturn() 可能会丢失。
正确的存根示例:
    当(模拟。isOk())。然后返回(真);
    when(mock.isOk()).thenThrow(异常);
    doThrow(exception).when(mock).someVoidMethod();
提示:
 1. 缺少 thenReturn()
 2. 你正试图存根最后的方法,你这个顽皮的开发者!

    在 org.mockito.exceptions.Reporter.unfinishedStubbing(Reporter.java:55)
    在 org.mockito.internal.progress.MockingProgressImpl.validateState(MockingProgressImpl.java:74)
    在 org.mockito.internal.progress.ThreadSafeMockingProgress.validateState(ThreadSafeMockingProgress.java:49)
    在 org.mockito.internal.MockHandler.handle(MockHandler.java:71)
    在 org.mockito.internal.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:36)
    在 org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:48)
    在 org.mockitousage.JavadocExamplesTest$Sample$$EnhancerByMockitoWithCGLIB$$d5ac41.getId()
    在 org.mockitousage.JavadocExamplesTest.probableMockitoBug(JavadocExamplesTest.java:404)
    在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    在 org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
    在 org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
于 2012-09-03T16:33:16.630 回答
4

这个错误通常在它实际发生的地方之后报告。如果您未能正确地存根某些东西,Mockito 通常直到您下次调用其中一个 Mockito 方法时才能知道。这可能在同一个测试方法中,在同一个类中稍后的测试方法,甚至是完全不同的测试类。

你引用的那行对我来说看起来不错。看一下它上面的行,您在其中调用了 Mockito 存根或验证方法。您很可能有一个when没有关联的thenReturn,thenthenThrow. 或者您可能verify缺少实际的方法调用。还有一些其他的可能性。

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

于 2012-08-30T00:01:46.020 回答
1

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

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

编辑 @DavidWallace 纠正了我,所以请注意(或者说是开明的),从 1.9 开始,您可以只提供要抛出的异常类,它会为您构建一个。

于 2012-08-29T22:52:48.923 回答