如何模拟一个被调用两次的方法和第二个方法调用的参数是使用Mockito输出的第一个方法调用

时间:2017-04-04 11:44:25

标签: java unit-testing junit mockito

public List<Object> getDummyData(String testString ) {      
    final List<String> result1 = utility.getData(testString);
    final List<String> result2 = utility.getData(result1.get(0).split(~)[0]);       
    // Processing of result2 and few more method calls      
    return someListOfObject;
}

我需要模拟具有上述方法调用的方法。当我使用以下代码时:

MainApp mock= Mockito.mock(MainApp.class);
List<String> mockList = Mockito.mock(ArrayList.class);
doReturn(mockList).when(mock).getData("str");

我在第二次方法调用时运行测试用例时收到IndexOutOfBoundsException。

2 个答案:

答案 0 :(得分:1)

该异常的原因是该行:

 utility.getData(result1.get(0).split(~)[0]);

您希望在第一次通话时拆分。 但你没有说明关于那个模拟的任何事情!当你没有指定任何东西时,mockito只会在模拟上调用方法时返回dummy / empty / null数据。

你不必这样做。您绝对执行模拟列表对象。您只需创建一个适合您测试的列表;像

List<String> dummyList = Arrays.asList("whatever", "strings", "you need");

只是为了说清楚:嘲笑是你的最后度假胜地。您使用它才能控制您需要控制的对象;并且不能以任何其他方式控制。

列表非常容易控制:通过创建一个包含您需要在该列表中的内容的列表。

问题的另一部分:当重复调用相同的方法时,您可以轻松地指示Mockito返回不同的结果;例如,显示为here

答案 1 :(得分:1)

您收到错误的原因是Mockito.mock(ArrayList.class)没有值,所以当get(0)获得IndexOutOfBoundsException时。

相反,您应该将数据放入真实列表中。

MainApp mock= Mockito.mock(MainApp.class);
List<String> resultA = Arrays.asList("some~value", "some~other~value");
doReturn(resultA).when(mock).getData("str");
List<String> resultB = Arrays.asList("other value", "more other values");
doReturn(resultB).when(mock).getData("some");

虽然上述方法可行,但我建议使用匹配器进行模拟,然后验证正确的结果。原因是如果测试失败,您将获得更好的错误消息。

MainApp mock= Mockito.mock(MainApp.class);

// Mock multiple return values
Mockito.when(mock.getData(anyString())
  .thenReturn(Arrays.asList("some~value", "some~other~value"))
  .thenReturn(Arrays.asList("other value", "more other values"));

List<SomeObjects> result = getDummyData("some-arg");
Mockito.verify(mock).getData("some-arg"); //Verify correct calls
Mockito.verify(mock).getData("some");

// verify result