web-dev-qa-db-ja.com

正しく見えるdoThrowの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.
19
Karl K

偶然出会ったのと同じ問題から、sampleはモックであり、sample.getId()を別の場所にスタブしていると思いますか?とにかく、それが私の場合この問題を引き起こした。

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

とにかく、sample.getId()を定数値に置き換えてみてください。これで問題が解決するはずです。テストで宣言された定数をモックとそれ以降の使用の両方に使用することを検討できます。次に、verifyに別の呼び出しを追加することで、テストしているメソッドでsample.getId()が使用されたことを確認することもできます。

20
Gijs

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:
未完成のスタブがここで検出されました:
-> at org.mockitousage.JavadocExamplesTest.probableMockitoBug(JavadocExamplesTest.Java:404)

例えばthen.Return()が欠落している可能性があります。
正しいスタブの例:
 when(mock.isOk())。thenReturn(true); 
 when(mock.isOk())。 thenThrow(exception); 
 doThrow(exception).when(mock).someVoidMethod(); 
ヒント:
 1. missingReturn()
 2. you最終メソッドをスタブしようとしています、あなたは開発者のいたずらです!
 
 org.mockito.exceptions.Reporter.unfinishedStubbing(Reporter.Java:55)
 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)
 org.mockitousage.JavadocExamplesTest $ S ample $$ EnhancerByMockitoWithCGLIB $$ d5ac41.getId()
 at org.mockitousage.JavadocExamplesTest.probableMockitoBug(JavadocExamplesTest.Java:404)
 at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.Java:37)
 org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.Java:62)
4
Rogério

このエラーは通常、実際に発生した場所の後に報告されます。適切にスタブに失敗した場合、Mockitoは通常、Mockitoメソッドの1つを呼び出した次の時間まで認識できません。これは、同じテストメソッド、同じクラスの新しいテストメソッド、またはまったく異なるテストクラスにある場合があります。

あなたが引用した行は私には問題ありません。 Mockitoのスタブまたは検証メソッドを呼び出す、上の行を見てください。 whenthenReturn、またはthenが関連付けられていないthenThrowがある可能性が非常に高くなります。または、実際のメソッド呼び出しが欠落しているverifyがある場合があります。他にもいくつかの可能性があります。

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

4

exceptionクラス自体ではなく、Exception.classのinstanceを指定する必要があります。

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

[〜#〜] edit [〜#〜]まあ@DavidWallaceは私を修正したので、1.9以降はスローする例外クラスを提供するだけで、君は。

0
Kevin Welker

私の場合ではなく

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

だった

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