使用 Mockito 测试 Java 增强的行为

2022-09-03 09:37:17

我想测试一个Java方法,该方法具有增强的Mockito。问题是,当我不知道如何设定对增强工作的期望时。以下代码来自 mockito google 组中的一个未解答的问题

import static org.mockito.Mockito.when;
import static org.testng.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.mockito.Mockito;
import org.testng.annotations.Test;

public class ListTest
{

  @Test
  public void test()
  {
    List<String> mockList = Mockito.mock(List.class);
    Iterator<String> mockIterator = Mockito.mock(Iterator.class);

    when(mockList.iterator()).thenReturn(mockIter);
    when(mockIter.hasNext()).thenReturn(true).thenReturn(false);
    when(mockIter.next()).thenReturn("A");

    boolean flag = false;
    for(String s : mockList) {
        flag = true;
    }
    assertTrue(flag);
  }
} 

for 循环中的代码永远不会被执行。为迭代器设置期望不起作用,因为 java 增强的 在内部不使用列表迭代器。设置对方法的期望也没有,因为增强的实现似乎也不会调用列表的方法。List.get()get()

任何帮助将不胜感激。


答案 1

嘲笑迭代器对我有用。请参阅下面的代码示例:

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.Collection;
import java.util.Iterator;

import org.junit.Before;
import org.junit.Test;

public class TestMockedIterator {

    private Collection<String> fruits;
    private Iterator<String> fruitIterator;

    @SuppressWarnings("unchecked")
    @Before
    public void setUp() {
        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);
    }

    @Test
    public void test() {
        int iterations = 0;
        for (String fruit : fruits) {
            iterations++;
        }
        assertEquals(3, iterations);
    }
}

答案 2

除非我遗漏了什么,否则您可能应该返回一个模拟值的真实列表。在这种情况下,请在生成器方法中构造测试字符串列表,然后直接返回该列表。在更复杂的情况下,您可以将列表的内容替换为模拟对象。

作为一个结束点,我无法想象为什么你真的需要模拟一个增强的for循环。单元测试的性质不适合这种级别的检查。这是一个有趣的问题。