如何使用Mockito正确模拟每个循环?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用Mockito正确模拟每个循环?相关的知识,希望对你有一定的参考价值。

我想测试我的方法,我需要模拟项目和行的向量来完成每个方法。

当我从Item类(在测试中)调用getRows()时,我准备了我想要得到的结果向量。

问题是测试中getRows方法的结果总是为空,因此这意味着doReturn语句在这里无法正常工作。

我错了什么?

class MyServiceTest {
@Mock
private Item mockedItem;

@Mock
private Row mockedRow;

@InjectMocks
@Spy
private MyService myService;

@Test
public void testMyMethod() {
    Vector<Row> rows = new Vector<Row>();
    Row row = new Row();
    rows.add(row);

    doReturn(rows).when(mockedItem).getRows();

    ...
    //some code to test the service

    }
}

class MyService {
    protected SomeObject myMethod(Vector<Item> items) {     
        for(Item item : items) {
            for(Row row : item.getRows()) {
               //cannot get here while debugging the test

               //some code
            }
        }
    ...
    }
}
class Item {
...
    public Vector<Row> getRows(){
       //return some vector of rows
    }
}
答案

@InjectMock是无用的,因为模拟向量是测试方法的参数,而不是被测试类的字段。 所以你需要什么都不注入。

你需要做的是创建一个Item的Vector,其中每个元素都是一个模拟,具有getRows()的预期行为:返回存根行。

这是一个示例代码:

// create stubbed rows
Vector<Row> rows = new Vector<Row>();
Row row = new Row();
rows.add(row);

// mock items Vector
Vector<Item> items = new Vector<>();
for (...){ // nb element to create
  Item mockedItem = Mockito.mock(Item.class);
  doReturn(rows).when(mockedItem).getRows();
  items.add(mockedItem);
}

然后通过传递向量来调用您测试的方法:

new MyService().myMethod(items);

请注意,Vector是一个古老而有缺陷的集合。 如果你不需要处理竞争条件,用户可以选择ListArrayList作为实现。

以上是关于如何使用Mockito正确模拟每个循环?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Mockito模拟DisplayMetrics

如何使用 Mockito 模拟由 Spring 应用程序上下文创建的对象以进行单元测试覆盖?

使用 Mockito 时,模拟和间谍有啥区别?

如何使用 Mockito 框架模拟我的服务

如何在 Mockito 中模拟全局变量

如何在 Java 中使用 Mockito 模拟结果集并填充它