Skip to main content
 首页 » 编程设计

java之如何通过 Mockito 验证是否使用预期参数(java.util.List 作为参数)调用了方法

2024年08月06日13kerrycode

您可以在下面看到 WorkWithArrayList 的示例类。这个类有两个方法 removeFirstThreeinsertDataremoveFirstThree 方法获取一个 List 作为参数并修改它,然后插入到数据库中。在 for 循环中,我展示了这个修改,就好像它正在删除 IntegerList 的第一个元素,并在每次迭代时插入数据。

我想实现的是验证 insertData 方法的参数。但是 verify 方法只检查第一个 verify(workWithArrayList).insertData(expected); 声明。

package test; 
 
import org.junit.Before; 
import org.junit.Test; 
 
import java.util.ArrayList; 
import java.util.List; 
 
import static org.mockito.Mockito.spy; 
import static org.mockito.Mockito.verify; 
 
public class MockitoVerifyWithArrayListTest { 
 
    private WorkWithArrayList workWithArrayList; 
    private List<Integer> actual; 
    private List<Integer> expected; 
 
    @Before 
    public void setUp() throws Exception { 
 
        workWithArrayList = spy(new WorkWithArrayList()); 
 
        actual = new ArrayList<>(); 
        actual.add(1); 
        actual.add(2); 
        actual.add(3); 
        actual.add(4); 
        actual.add(5); 
        actual.add(6); 
 
        expected = new ArrayList<>(); 
        expected.add(1); 
        expected.add(2); 
        expected.add(3); 
        expected.add(4); 
        expected.add(5); 
        expected.add(6); 
    } 
 
    @Test 
    public void test() throws Exception { 
 
        workWithArrayList.removeFirstThree(actual); 
 
        expected.remove(0); 
        verify(workWithArrayList).insertData(expected); 
 
        expected.remove(0); 
        verify(workWithArrayList).insertData(expected); 
 
        expected.remove(0); 
        verify(workWithArrayList).insertData(expected); 
    } 
 
    public class WorkWithArrayList { 
 
        public void removeFirstThree(List<Integer> integers) { 
 
            for (int i = 0; i < 3; i++) { 
 
                integers.remove(0); 
                insertData(integers); 
            } 
        } 
 
        public void insertData(List<Integer> integers) { 
 
        } 
    } 
} 

当我运行这个测试时,我遇到了以下错误:

Argument(s) are different! Wanted: 
workWithArrayList.insertData( 
    [2, 3, 4, 5, 6] 
); 
-> at test.MockitoVerifyWithArrayListTest.test(MockitoVerifyWithArrayListTest.java:46) 
Actual invocation has different arguments: 
workWithArrayList.insertData( 
    [4, 5, 6] 
); 
-> at test.MockitoVerifyWithArrayListTest.test(MockitoVerifyWithArrayListTest.java:43) 

编辑如果我们查看Mockito.verify 方法的javadoc,我们可以看到:
使用 equals() 方法比较传递的参数。

但是变量 actualexpected 是相等的,即使我们删除了两者的第一个元素,它们也将保持相等。我很感兴趣为什么这个测试会失败。

请您参考如下方法:

除非我遗漏了一些真正重要的东西,否则你会把事情搞混,从而让自己更难测试。

你看,修改一个列表和列表放在某处是两种不同的责任。因此,您将两个方面都强加到同一个类中会使测试变得困难!

这里有一个更好的方法:分离关注点。创建一个执行列表操作的类。该类(class)可能无需任何 模拟即可进行测试! 您创建一个列表;将其交给列表修改类;并检查返回的内容。只需断言需要!

然后,当您知道列表操作有效时,您只需要测试将列表写入数据库是否有效;而且您不关心要编写的列表实际上是什么样的!