6

1 つのメソッドに対して 2 つのカスタム マッチャーを使用したいと考えています。基本的には、メソッドに VALUE_A を渡せば RESULT_A を返したいし、VALUE_B を渡せば RESULT_B を返したい。コードの抜粋は次のとおりです。

class IsNonEmpty extends ArgumentMatcher<Get> {
    public boolean matches(Object get) {
        //For some reason, this method is called when I assign the IsEmpty matcher to MockHtable.get()
        //When this happens, the value of the get argument is null, so this method throws an NPE

        return Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key)); 
    }
}

class IsEmpty extends ArgumentMatcher<Get> {
    public boolean matches(Object get) {
        return !(Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key))); 
    }
}      

[...]

//This line executes just fine
Mockito.when(mockHTable.get(Mockito.argThat(new IsNonEmpty()))).thenReturn(dbResult);

[...]

//This line calls IsNonEmpty.matches() for some reason.  IsNonEmpty.matches() throws an NPE
Mockito.when(mockHTable.get(Mockito.argThat(new IsEmpty()))).thenReturn(emptyResult);

IsEmpty カスタム マッチャーを mockHTable.get() メソッドに割り当てると、IsNonEmpty.matches() 関数が呼び出されます。なぜこれを行っているのかわかりません。そこで、IsNonEmpty クラスを次のように変更します。

class IsNonEmpty extends ArgumentMatcher<Get> {
    public boolean matches(Object get) {
        //For some reason, this method is called when I assign the IsEmpty matcher.  Weird, no?
        if(get == null) {
            return false;
        }

        return Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key)); 
    }
}

そして、すべてがうまくいきます!IsNonEmpty.matches() は、IsEmpty マッチャーを mockHTable.get() 関数に割り当てたときに引き続き呼び出されますが、マッチャーは本来の方法で正確に動作します。

それで、取引は何ですか?なぜこれが起こるのですか?私の回避策は、この風変わりな動作を補う適切な方法ですか、それとも間違っていますか?

4

1 に答える 1

11

IsNonEmpty.matches()スタブの 2 行目で gets が呼び出される理由は、Mockito.argThat(new IsEmpty())が null を返し、それが に渡されるためmockHTable.get()です。この呼び出しは、一致するかどうかを確認するために、以前のスタブに対してチェックする必要があります。それは を呼び出すことを意味しIsNonEmpty.matches()ます。

なぜこれでテストが失敗するのかわかりません。すべてのコードを見ないとわかりません。

ただし、同じモックを複数回スタブする必要がある場合は常にdoReturn...when代わりに使用することを真剣にお勧めします。when...thenReturnそうすれば、このような問題は発生しません。実際、doReturn...whenほとんどwhen...thenReturndoThrowdoAnswerwhen...thenReturn.

スタブ行の 1 つをdoReturn...when構文で書き直すと、次のようになります。もう一方も同様です。

Mockito.doReturn(dbResult).when(mockHTable).get(Mockito.argThat(new IsNonEmpty()));  

最後に、Mockito 開発チーム (私はそのメンバーです) を代表して嘆願します。ここでMockitoにバグがあると思われる場合-そしてあなたの説明から、おそらくあると思います-どちらかをお願いします

  • Mockito メーリング グループ (mockito@googlegroups.com) にメッセージを送信するか、
  • Mockito の問題リスト (http://code.google.com/p/mockito/issues/list) で問題を提起してください。

主要な行が何であるかだけでなく、実際に完全な例を投稿できると、Mockito チームにとって役に立ちます。Mockito の問題の原因がまったく予期しない場所にある場合があります。

于 2012-04-27T06:06:16.343 に答える