【问题标题】:Mockito verify with list that changesMockito 使用更改的列表进行验证
【发布时间】:2017-04-25 03:29:22
【问题描述】:

我有一个简单的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();
}

【问题讨论】:

    标签: java list collections mockito


    【解决方案1】:

    这里不完全确定,但这似乎是 Mockito 的限制(但不要引用我的话)。起初我认为这可以通过ArgumentCaptor 解决,但它捕获了相同的实例,当您验证它时,它已经被修改了。

    根据this answer,您可以在调用方法时使用Answer 来验证参数。由于Bar::action 的返回类型为void,因此存根它需要稍微不同的方法。 Mockito docs 建议使用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 块中,当列表传递给模拟时,您可以访问该列表。断言可以在那里完成,或者您可以存储参数并稍后再做。我会说这个解决方案不是很优雅。

    【讨论】:

      猜你喜欢
      • 2011-09-04
      • 2017-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      • 2019-11-27
      • 2013-08-23
      相关资源
      最近更新 更多