您可以在下面看到 WorkWithArrayList
的示例类。这个类有两个方法 removeFirstThree
和 insertData
。 removeFirstThree
方法获取一个 List
作为参数并修改它,然后插入到数据库中。在 for
循环中,我展示了这个修改,就好像它正在删除 Integer
的 List
的第一个元素,并在每次迭代时插入数据。
我想实现的是验证 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()
方法比较传递的参数。
但是变量 actual
和 expected
是相等的,即使我们删除了两者的第一个元素,它们也将保持相等。我很感兴趣为什么这个测试会失败。
请您参考如下方法:
除非我遗漏了一些真正重要的东西,否则你会把事情搞混,从而让自己更难测试。
你看,修改一个列表和将列表放在某处是两种不同的责任。因此,您将两个方面都强加到同一个类中会使测试变得困难!
这里有一个更好的方法:分离关注点。创建一个执行列表操作的类。该类(class)可能无需任何 模拟即可进行测试! 您创建一个列表;将其交给列表修改类;并检查返回的内容。只需断言需要!
然后,当您知道列表操作有效时,您只需要测试将列表写入数据库是否有效;而且您不关心要编写的列表实际上是什么样的!