如何使用 Mockito 模拟 forEach 行为 [英] How to mock forEach behavior with Mockito

查看:166
本文介绍了如何使用 Mockito 模拟 forEach 行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做以下工作,但我不知道如何正确模拟 forEach 行为.(代码取自相关问题使用 Mockito 测试增强行为的 Java )

I want to make the following work, but I don't know how to mock forEach behavior properly. (The code is taken from a related question Testing Java enhanced for behavior with Mockito )

@Test
public void aa() {
  Collection<String> fruits;
  Iterator<String> fruitIterator;

  fruitIterator = mock(Iterator.class);
  when(fruitIterator.hasNext()).thenReturn(true, true, true, false);
  when(fruitIterator.next()).thenReturn("Apple")
      .thenReturn("Banana").thenReturn("Pear");

  fruits = mock(Collection.class);
  when(fruits.iterator()).thenReturn(fruitIterator);
  doCallRealMethod().when(fruits).forEach(any(Consumer.class));

  // this doesn't work (it doesn't print anything)
  fruits.forEach(f -> {
    mockObject.someMethod(f); 
  });

  // this works fine
  /*
  int iterations = 0;
  for (String fruit : fruits) {
    mockObject.someMethod(f); 
  }
  */

  // I want to verify something like this
  verify(mockObject, times(3)).someMethod(anyString());
}

任何帮助将不胜感激.

推荐答案

Collection接口的方法forEach是一个防御者"方法;它不使用Iterator,而是调用传递给方法的Consumer.

The method forEach of the Collection interface is a "defender" method; it does not use Iterator but call the Consumer passed to the method.

如果你使用的是Mockito 2+版本(*),你可以要求调用Collection接口的默认方法forEach:

If you are using Mockito version 2+ (*), you can ask the default method forEach of the Collection interface to be called:

Mockito.doCallRealMethod().when(fruits).forEach(Mockito.any(Consumer.class));

请注意,defender"方法实际上会请求一个 Iterator 来遍历集合,因此将使用您在测试中模拟的 Iterator.如果模拟集合没有提供 Iterator 就不会工作,就像 when(fruits.iterator()).thenReturn(fruitIterator)

Note that the "defender" method is actually going to request an Iterator to traverse the collection, hence will use the Iterator you mocked in your test. It wouldn't work if no Iterator was provided by the mocked collection, as with when(fruits.iterator()).thenReturn(fruitIterator)

(*): Mockito 从版本 2 开始增加了支持 Java 8 默认(defender")方法的可能性 - 你可以检查跟踪问题 这里.

(*): Mockito has added the possibility to support Java 8 default ("defender") method since version 2 - you can check the tracking issue here.

这篇关于如何使用 Mockito 模拟 forEach 行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆