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()どこかでスタブしましたか? とにかく、それが私の場合にこの問題を引き起こしました。

doThrow何らかの理由で、この方法で使用されるスタブに渡す引数の 1 つが、モックしたメソッドの結果である場合、Mockito は動揺します。おそらく、無限ループを回避するための一種の再入可能チェックだと思いますが、わかりません。

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() が欠落している可能性があります。
正しいスタブの例:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(例外);
    doThrow(例外).when(モック).someVoidMethod();
ヒント:
 1. thenReturn() がありません
 2. final メソッドをスタブしようとしている、このいたずらな開発者!

    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(ネイティブメソッド)
    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 メソッドの 1 つを呼び出すまでわかりません。これは、同じテスト メソッド、同じクラスの後のテスト メソッド、またはまったく異なるテスト クラスにある可能性があります。

あなたが引用した行は私にはうまく見えます。その上の行を見てください。Mockito のスタブまたは検証メソッドを呼び出す場所です。またはwhenが関連付けられていないthenReturnがある可能性が非常に高いです。または、実際のメソッド呼び出しが欠落している がある可能性があります。他にもいくつかの可能性があります。thenthenThrowverify

引用した行の上にエラーが見つからない場合は、さらにコードを投稿してください。詳しく調べます。

于 2012-08-30T00:01:46.020 に答える
1

Exception クラス自体ではなく、Exception.classのインスタンスを提供する必要があります。

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

編集 まあ@DavidWallaceは私を修正したので、1.9以降、スローする例外クラスを提供するだけで、例外クラスを構築できることに注意してください(またはむしろ啓発されます)。

于 2012-08-29T22:52:48.923 に答える