私はList
オブジェクトを受け取るメソッドを持つコールバックインターフェイスを持っています。 InOrder
を使用して、コールバックメソッドが正しい順序で適切なパラメータで適切な回数呼び出されていることを確認します。InOrderを使用して、変更されたListオブジェクトでメソッド呼び出しを確認する
問題はMockitoは、私は、メソッドに同じList
オブジェクトを渡すと呼び出しの間で、それを修正していますので、混乱してきているように見えるということです。 InOrder.verify()
を呼び出すと、List
オブジェクトの値が、そのメソッド呼び出しが実行された時点で確認されます。
コード:
public class Test {
@Test
public void test() {
Callback callback = Mockito.mock(Callback.class);
InOrder inOrder = Mockito.inOrder(callback);
{
List<String> list = new ArrayList<String>(); //note: this List object is inaccessible from the unit test in my real use-case
callback.foo("name1", list);
list.add("value");
callback.foo("name2", list);
}
inOrder.verify(callback).foo("name1", Arrays.<String> asList()); //fails here
inOrder.verify(callback).foo("name2", Arrays.asList("value"));
}
interface Callback {
void foo(String name, List<String> list);
}
}
エラーメッセージ:
Argument(s) are different! Wanted:
callback.onFoo([]);
Actual invocation has different arguments:
callback.onFoo([value]);
各コールバックメソッドの呼び出しにList
オブジェクトのコピーを渡すは、テストパスを作ります。しかし、メソッドが呼び出されるたびに、新しいList
を作成したくありません。
に渡すことができるMockSettings
オブジェクトを見ましたが、役立つものは何も見つかりませんでした。
This questionは鉱山に似ています。しかし、この解決策では、各メソッド呼び出しに渡されたコレクションの内容は検証されません。コレクション(anyCollectionOf()
)が渡されたということだけを確認します。 最終結果を確認しますが、では個々の呼び出しではありません。
This answerは、潜在的な解決策を提供するように思われた。メソッドに渡されるオブジェクトを取得するのにArgumentCaptor
を使用します。しかし、最初のメソッド呼び出しを検証するためにこのメソッドを使用すると、すべての変更がに行われた後にList
オブジェクトが返され、テストに失敗します。 List
オブジェクトを戻す必要があります。オブジェクトの状態はList
オブジェクトの状態と一致し、その正確な呼び出しはです。
ArgumentCaptor<List> argument = ArgumentCaptor.forClass(List.class);
inOrder.verify(callback).foo(Mockito.eq("name1"), argument.capture());
assertEquals(Arrays.asList(), argument.getValue()); //fails: "expected: <[]> but was: <[value]>
inOrder.verify(callback).foo(Mockito.eq("name2"), argument.capture());
assertEquals(Arrays.asList("value"), argument.getValue());
粒度を犠牲にすることなくこのテストに合格するにはどうすればよいですか?
私の提案した複製で自分のanserを使用する場合は、キャプチャ機能でリストのコピーを作成します。その後、検証段階で、それらのコピーが正しいかどうかを調べることができます。 – SpaceTrucker
ありがとう@SpaceTrucker。理想的ではありませんが、機能します。 – Michael