Java Mockito:模拟将在 for 循环中循环的数组列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18483176/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 02:02:40  来源:igfitidea点击:

Mockito: mocking an arraylist that will be looped in a for loop

javaunit-testingmockito

提问by Rebane Lumes

I have a method under test that contains the following snippet:

我有一个正在测试的方法,其中包含以下代码段:

private void buildChainCode(List<TracedPath> lines){
    for(TracedPath path : lines){
        /.../
    }
}

My unit test code looks like this:

我的单元测试代码如下所示:

public class ChainCodeUnitTest extends TestCase {

    private @Mock List<TracedPath> listOfPaths;
    private @Mock TracedPath tracedPath;

    protected void setUp() throws Exception {
        super.setUp();
        MockitoAnnotations.initMocks(this);
    }

    public void testGetCode() {
        when(listOfPaths.get(anyInt())).thenReturn(tracedPath);

        ChainCode cc = new ChainCode();
        cc.getCode(listOfPaths);

        /.../
    }
}

The problem is, that while running the test, the test code never enters the for loop. What when conditions should I specify, so that the for loop would be entered? Currently I have specified when(listOfPaths.get(anyInt())).thenReturn(tracedPath), but I guess it is never used.

问题是,在运行测试时,测试代码永远不会进入 for 循环。我应该在什么时候指定条件,以便进入 for 循环?目前我已指定when(listOfPaths.get(anyInt())).thenReturn(tracedPath),但我想它从未使用过。

采纳答案by Dawood ibn Kareem

Your problem is that when you use a collection in a for-each loop, its iterator()method gets called; and you haven't stubbed that particular method.

您的问题是,当您在 for-each 循环中使用集合时,它的iterator()方法会被调用;并且您还没有使用该特定方法。

Instead of mocking the list, I strongly recommend you just pass a real list, where the elements are just your mocked TracedPath, as many times as you want it. Something like

与其模拟列表,我强烈建议您只传递一个真正的列表,其中的元素只是您的模拟对象TracedPath,次数不限。就像是

listOfPaths = Arrays.asList(mockTracedPath, mockTracedPath, mockTracedPath);

回答by Chris Mantle

The Java For-Each loop used inside your buildChainCodemethod isn't calling get(), as you already figured out - it's using the iterator()method defined in Collection<E>, which List<E>extends.

您的buildChainCode方法中使用的 Java For-Each 循环并未调用get(),正如您已经发现的那样 - 它使用的是 中iterator()定义的方法Collection<E>,它List<E>扩展了 。

I reallywouldn't recommend mocking the list. There's no advantage to it, unless you absolutely must check that the list was iterated through, and even then, it's better to assert on or verify the results of your class's behaviour given certain inputs.

真的不建议嘲笑列表。它没有任何优势,除非您绝对必须检查列表是否已迭代,即使如此,在给定某些输入的情况下,最好断言或验证类的行为结果。

Pass some implementation of List<E>like LinkedList<E>with tracedPathin it.

在其中传递List<E>like LinkedList<E>with 的一些实现tracedPath