首页 文章

Mockito验证:在验证()期间验证,而不是在模拟方法调用期间验证

提问于
浏览
4

我用方法列表调用方法performAction并验证相同的方法 . 调用此方法后,我修改了一些“对象” .

Mockito验证失败说参数不匹配(显示修改过的对象)但我可以在调试模式下看到对象在需要时是正确的 .

理想情况下,这不应该发生,因为应该在实际调用方法时应用验证 . 在测试方法验证调用期间验证是否适用于模拟方法调用时?

测试类

@Test
public void test() throws Exception {
    List<ABC> objects = new ArrayList<ABC>();
    //populate objects.
    activity.performActions(objects);               
    verify(activity, times(1)).doActivity(objects);
}

测试方法:

public void performActions(List<ABC> objects) {

    activity.doActivity(urlObjects2PerformAction);
    //Modify objects                

}

我得到的错误如下(这是完整的代码 . 我给出了最小的可能代码段):

Argument(s) are different! Wanted:
activity.doActivity(
.......
......

3 回答

  • 7

    以前曾经问过这个问题 - 在Can Mockito verify parameters based on their values at the time of method call?

    当您调用已经使用Mockito存根的方法时,Mockito将存储传递给它的参数,以便您以后可以使用 verify . 也就是说,它存储对象引用,而不是对象本身的内容 . 如果稍后更改这些对象的内容,则 verify 调用将其参数与更新的对象进行比较 - 它不会生成原始对象的深层副本 .

    如果您需要验证对象的内容是什么,则需要使用

    • 在方法调用时自己存储它们;要么

    • 在方法调用时验证它们 .

    正确的方法是使用Mockito Answer . 因此,对于第二个选项,您将创建一个执行验证的 Answer ,如果参数值不正确,则抛出 AssertionFailedError ;而不是在测试结束时使用 verify .

  • 1

    verify 比较调用 verify 时的参数内容,而不是调用模拟方法时的参数内容 . 如果修改了列表的内容,则 verify 将使用修改后的值 .

    另一种方法是使用 Answer 来在调用方法后立即检查参数,或者可以创建新列表而不是修改旧列表 .

  • 0

    现在可以使用ArgumentCaptor解决这个问题

    @Test
    public void test() throws Exception {
        List<ABC> objects = new ArrayList<ABC>();
        ArgumentCaptor<List<ABC> objectsCaptor = ArgumentCaptor<List.class>;
        //populate objects.
        activity.performActions(objects);               
        verify(activity, times(1)).doActivity(objectsCaptor.capture());
    }
    

相关问题