我有一個回調接口,其方法需要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
對象,你可以通過Mockito.mock()
,但沒有看到任何可能的幫助。
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