2013-08-21 16 views
5

に異なるパラメータを持つ1つのモックに呼び出された方法の一つの方法を確認するために、私は別のパラメータを使用して順番に呼び出されたモックのメソッドをテストしたいMockitoは、次のコードを使用する</p> <p>は、私が試した:順

それは私にエラーを与えたとして
InOrder inOrder = inOrder(myobject); 
    inOrder.verify(myobject).println(any(String.class)); 
    inOrder.verify(myobject).println(any(String.class)); 
    inOrder.verify(myobject).println(""); 
    inOrder.verify(myobject).println("myfolder"); 
    inOrder.verify(myobject).println(""); 
    inOrder.verify(myobject).println(System.getProperty("user.home")); 

しかし、これは動作していないよう

inOrder.verify(myobject).println(any(String.class)); 

は8回と呼ばれてきたと言います。これは間違いありませんが、注文には対処できません。

私が確認したい:

The println method of `myobject` is first called with any string parameter 
    Then it is called with any string parameter again 
    Then it is called by an empty string 
    Then it is called by string "myfolder" 
    ...... 

どのように私はこれを達成することができますか?

EDIT:

エラーメッセージは次のとおりです。

org.mockito.exceptions.verification.VerificationInOrderFailure: 
Verification in order failure: 
printWriter.println(<any>); 
Wanted 1 time: 
-> at com.mycompany.MyUnitTest.mytest(MyrUnitTest.java:107) 
But was 8 times. 
+0

エラーの内容を正確に表示できますか? –

+0

ありがとうございます。エラーメッセージを追加しました。 – KKKCoder

+0

あなたは 'inOrder.verify(myobject、times(2))。println(any(String.class));'でそれを呼び出そうとしましたか? –

答えて

5

printlnのすべての呼び出しで引数のキャプチャを使用して、取得した各値を確認します。

@Captor ArgumentCaptor<String> stringCaptor; 

// ... 

@Test public void myTest() { 

    // ... 

    verify(myobject, 6).println(stringCaptor.capture()); 
    assertEquals("", stringCaptor.getAllValues()[2]); 
    assertEquals("myfolder", stringCaptor.getAllValues()[3]); 
    assertEquals("", stringCaptor.getAllValues()[4]);  
    assertEquals(System.getProperty("user.home"), stringCaptro.getAllValues()[5]); 
1

さて、この答えは、あまりにも一般的ではなく、どちらかエレガントではありません。

私にとっては、問題は、any(String.class)が原因であると思われます。つまり、すべての種類の文字列に一致します。だから、いくつかの例外を除いて、すべての種類の文字列にマッチする正規表現を作成しようとしました:"" or "myfolder" or System.getProperty("user.home")。そして、コードは次のとおりです。

import static org.mockito.AdditionalMatchers.*; 

inOrder.verify(myobject, times(2)).println(
      and(anyString(), not(
        or(eq(""), or(eq("myfolder"), eq(System.getProperty("user.home"))))))); 

それは私mockitoから奇妙な実行時例外が発生するため(一部の神秘的な理由で、私もローカル変数にand(...)を抽出することはできません、これは読みやすいようにフォーマットする課題そのものでありますスタッビングや検証の外でマッチャーを使用することはできません)。

3

David Wallaceのソリューションは、私がMockitoを使用することで知っている最高のものですが、嘲笑は必ずしも仕事に適したツールではないことに注意してください。

モックの代わりにPrintWriter(ByteArrayOutputStream)を渡して、ByteArrayOutputStreamが期待どおりの出力と一致することを確認してください。

@Test public void yourTest() { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    PrintWriter writer = new PrintWriter(baos); 
    systemUnderTest.doThing(writer); 

    assertTrue(writer.toString().endsWith(
     "\n\nmyfolder\n\n" + System.getProperty(user.home) + "\n")); 
} 

これは、出力が方法が正確に正しい順序で呼び出されたいないことを、あなたはそれを期待道に見えるということであるあなたが実際にテストしているロジックにおそらく近いです。 MessageFormatterテンプレートへの切り替えや、改行をStringBuilderに組み込み、printlnを一度呼び出すなど、自由にリファクタリングすることができます。他のprintまたはprintln()コールを使用している人とは隔離されています。そうしないと、Mockitoベースのテストが破られます。

必要に応じて、正規表現PatternまたはScannerを使用して正当性を検証することもできます。 Pattern.quoteは、期待どおりの文字列をプログラムで構築する必要がある場合には、正規表現の部分文字列をエスケープするのに役立ちます(ここではuser.homeと同じです)。

+0

+1このテストはJMockit Verifications APIを使って非常にうまく書けますが、結局はこれを酷使し過ぎてしまいます。完全な文字列出力をキャプチャし、それが正規表現で整形されているかどうかをチェックする方がはるかに良い解決策です。 –

関連する問題