我在Kotlin中使用Mockito检查列表是否正确分页
我使用此代码
logic.searchItems(filter)
verify(vm).setItems(all.subList(0, 10), true)
logic.loadNext()
verify(vm).setItems(all.subList(0, 20), true) (1)
logic.loadNext()
verify(vm).setItems(all.subList(0, 30), true) (2)
从理论上讲这应该可行,但是我在(1)和(2)中得到了太多的调用异常。
如果我使用(1)中的times(1)和(2)中的times(2),则测试通过。但我希望验证是否使用这些特定参数调用了该方法。
这可以用Mockito完成吗?
答案 0 :(得分:0)
经过一些测试,我发现问题是在我的逻辑中,我将结果添加到了相同的列表中,然后像这样发送回去:
addItems(results:List<Item>()){
//verifications here
myItems.addAll(results)
vm.setItems(myItems,true)
}
出于某种原因,这使模仿者认为这是相同的调用?
当我这样做时,它会起作用
addItems(results:List<Item>()){
//verifications here
myItems.addAll(results)
vm.setItems(myItems.map { it.copy() },true)
}
我不知道这是错误还是预期的行为,但至少可以奏效
编辑:
好吧,我觉得自己是个白痴,因为它根本不是一个bug,确实是预期的行为,并且为我节省了以后的麻烦
使用捕获程序时,我发现调用setItems
方法时,Mockito会保留对返回列表的引用。
下次调用它时,我曾经将项目添加到myItems中,而Mockito保留了新的引用
但是由于我执行了addAll
操作,所以以前保存的引用也得到了更新,因此,在我调用Mockito时,确实需要Mockito使用times(2)方法是很正常的,因为它的列表位于第一个调用已更新,将与第二个列表匹配。
看起来正确的方法是发送该列表的副本,以使viewModel不能以任何方式更改原始列表
答案 1 :(得分:0)
使用这种参数,作为具有特定内容的集合,我建议使用ArgumentCaptor
功能。因此,您将能够捕获传递的参数,并随后使用Hamcrest或AssertJ之类的工具声明其值/状态:
final ArgumentCaptor<List> captorListOne = ArgumentCaptor.forClass(List.class);
final ArgumentCaptor<List> captorListTwo = ArgumentCaptor.forClass(List.class);
final ArgumentCaptor<List> captorListThree = ArgumentCaptor.forClass(List.class);
verify(vm).setItems(captorListOne.capture(), true)
logic.loadNext()
verify(vm).setItems(captorListTwo.capture(), true)
logic.loadNext()
verify(vm).setItems(captorListThree.capture(), true)
List listToAssert = captorListOne.getValue();
...