莫基托;验证方法被列表调用,忽略列表中元素的顺序
我有一个类(ClassA)来获取目录中的文件。它扫描给定目录以查找与正则表达式匹配的文件。对于每个匹配的文件,它会将一个文件对象添加到列表中。处理完目录后,它会将文件列表传递给另一个类 (ClassB) 进行处理
我正在为ClassA编写单元测试,所以我使用Mockito模拟ClassB,并将其注入ClassA。然后,我想在不同的情况下验证传递给ClassB的列表的内容(即我的模拟)
我已将代码剥离到以下内容
public class ClassA implements Runnable {
private final ClassB classB;
public ClassA(final ClassB classB) {
this.classB = classB;
}
public List<File> getFilesFromDirectories() {
final List<File> newFileList = new ArrayList<File>();
// ...
return newFileList;
}
public void run() {
final List<File> fileList = getFilesFromDirectories();
if (fileList.isEmpty()) {
//Log Message
} else {
classB.sendEvent(fileList);
}
}
}
测试类如下所示
@RunWith(MockitoJUnitRunner.class)
public class AppTest {
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@Mock
private ClassB mockClassB;
private File testFileOne;
private File testFileTwo;
private File testFileThree;
@Before
public void setup() throws IOException {
testFileOne = folder.newFile("testFileA.txt");
testFileTwo = folder.newFile("testFileB.txt");
testFileThree = folder.newFile("testFileC.txt");
}
@Test
public void run_secondFileCollectorRun_shouldNotProcessSameFilesAgainBecauseofDotLastFile() throws Exception {
final ClassA objUndertest = new ClassA(mockClassB);
final List<File> expectedFileList = createSortedExpectedFileList(testFileOne, testFileTwo, testFileThree);
objUndertest.run();
verify(mockClassB).sendEvent(expectedFileList);
}
private List<File> createSortedExpectedFileList(final File... files) {
final List<File> expectedFileList = new ArrayList<File>();
for (final File file : files) {
expectedFileList.add(file);
}
Collections.sort(expectedFileList);
return expectedFileList;
}
}
问题是这个测试在Windows上工作得很好,但在Linux上失败了。原因是在Windows上,ClassA列出文件的顺序与预期列表相匹配,因此行
verify(mockClassB).sendEvent(expectedFileList);
导致问题 expecetdFileList = {FileA, FileB, FileC} 在 Windows 上,而在 Linux 上,它将是 {FileC, FileB, FileA},因此验证失败。
问题是,我如何在Mockito中解决这个问题。有没有办法说,我希望用这个参数调用这个方法,但我不在乎列表内容的顺序。
我确实有一个解决方案,我只是不喜欢它,我宁愿有一个更干净,更易于阅读的解决方案。
我可以使用 ArgumentCaptor 将实际值传递到模拟中,然后对其进行排序,并将其与我的预期值进行比较。
final ArgumentCaptor<List> argument = ArgumentCaptor.forClass(List.class);
verify(mockClassB).method(argument.capture());
Collections.sort(expected);
final List<String> value = argument.getValue();
Collections.sort(value);
assertEquals(expecetdFileList, value);