У меня есть класс (ClassA), который получает файлы в каталоге. Он сканирует данный каталог для файлов, соответствующих регулярному выражению. Для каждого соответствующего файла он добавляет объект File в список. После обработки каталога он передает список файлов другому классу (ClassB) для обработки
Я пишу модульные тесты для ClassA, поэтому я издеваюсь над ClassB, используя Mockito, и вводя его в 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. Причина в том, что в окнах порядок, в котором ClassA отображает файлы, соответствует ожидаемому списку, поэтому строка
verify(mockClassB).sendEvent(expectedFileList);
вызывает проблему expecetdFileList = {FileA, FileB, FileC} в Windows, тогда как в Linux это будет {FileC, FileB, FileA}, поэтому проверка не выполняется.
Вопрос в том, как мне обойти это в Mockito. Есть ли способ сказать, я ожидаю, что этот метод будет вызван с этим параметром, но меня не интересует порядок содержимого списка.
У меня есть решение, мне просто не нравится, я бы предпочел бы более чистое, удобное для чтения решение.
Я могу использовать ArgumentCaptor, чтобы получить фактическое значение, переданное в mock, затем можно отсортировать его и сравнить его с моими ожидаемыми значениями.
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);