簡體   English   中英

Mockito驗證更改列表

[英]Mockito verify with list that changes

我有一個簡單的Bar對某些字符串執行操作:

public interface Bar {

  void action(List<String> strings);

}

然后我的Foo正在測試中。 它會隨着時間的推移建立一個字符串列表,然后最終使用Bar來處理它們。 處理完成后,隊列將被清除。

public class Foo {

  private final Bar bar;
  private final List<String> strings;

  public Foo(Bar bar) {
    this.bar = bar;
    this.strings = new ArrayList<>();
  }

  public void addStrings(String... strings) {
      Collections.addAll(this.strings, strings);
  }

  public void processStrings() {
    bar.action(strings);
    strings.clear();
  }

}

我試圖驗證Bar.action被預期的字符串調用。 然而,沒有的Mockito不檢測與實際參數的真實調用,因為調用時所使用的名單Bar.action被事后清除。

我可能做錯了什么,但這對我來說聞起來像個臭蟲。 這是測試:

@Test
public void shouldVerify() {
    // Given
    Bar bar = mock(Bar.class);
    Foo foo = new Foo(bar);
    foo.addStrings("Hello", "World");
    foo.addStrings("!!!");
    // When
    foo.processStrings();
    // Then
    verify(bar).action(Arrays.asList("Hello", "World", "!!!"));
}

比較失敗:

預期:bar.action([Hello,World,!!!]);

實際:bar.action([]);

可以肯定的是,注釋掉strings.clear()可以讓Mockito正確驗證。


我可以通過制作一個新列表傳遞給Bar來解決這個問題,例如:

public void processStrings() {
  bar.action(new ArrayList<>(strings));
  strings.clear();
}

這里不完全確定,但這似乎是Mockito的限制(但不要引用我的話)。 起初我認為這可以通過ArgumentCaptor解決,但它捕獲相同的實例,當您驗證它時,它已經被修改。

根據這個答案,您可以使用Answer來驗證調用方法時的參數。 由於Bar::action的返回類型為void,因此存根需要稍微不同的方法。 Mockito文檔建議使用doX()系列方法。

public void name() {
    Bar bar = mock(Bar.class);
    doAnswer(invocation -> {
        Object[] args = invocation.getArguments();
        List<String> list = (List<String>) args[0];
        assertThat(list.size(), is(3));
        return null;
    }).when(bar).action(anyList());

    Foo foo = new Foo(bar);
    foo.addStrings("Hello", "World");
    foo.addStrings("!!!");
    foo.processStrings();
}

doAnswer塊中,您可以在將列表傳遞給模擬時訪問該列表。 斷言可以在那里完成,或者您可以存儲參數並在以后執行。 我會說解決方案不是很優雅。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM