简体   繁体   English

如何使用Mockito模拟forEach行为

[英]How to mock forEach behavior with Mockito

I want to make the following work, but I don't know how to mock forEach behavior properly. 我想做以下工作,但我不知道如何正确模拟forEach行为。 (The code is taken from a related question Testing Java enhanced for behavior with Mockito ) (代码摘自一个相关的问题, 测试Java增强了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());
}

Any help will be very appreciated. 任何帮助将不胜感激。

The method forEach of the Collection interface is a "defender" method; Collection接口的forEach方法是“防御者”方法; it does not use Iterator but call the Consumer passed to the method. 它不使用Iterator而是调用传递给该方法的Consumer

If you are using Mockito version 2+ (*), you can ask the default method forEach of the Collection interface to be called: 如果您使用的是Mockito版本2+(*),则可以要求调用Collection接口的默认方法forEach

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

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. 请注意,“ defender”方法实际上将请求一个Iterator遍历该集合,因此将使用您在测试中模拟的Iterator It wouldn't work if no Iterator was provided by the mocked collection, as with when(fruits.iterator()).thenReturn(fruitIterator) 如果嘲笑的集合未提供Iterator则该方法将无法正常工作,例如when(fruits.iterator()).thenReturn(fruitIterator)

(*): Mockito has added the possibility to support Java 8 default ("defender") method since version 2 - you can check the tracking issue here . (*):Mockito从版本2开始增加了支持Java 8默认(“防御者”)方法的可能性-您可以在此处检查跟踪问题。

Iterator mockIterator = mock(Iterator.class);
doCallRealMethod().when(fruits).forEach(any(Consumer.class));
when(fruits.iterator()).thenReturn(mockIterator);
when(mockIterator.hasNext()).thenReturn(true, false);
when(mockIterator.next()).thenReturn(mockObject);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM