Вопрос или проблема
У меня есть несколько тестов Junit, которые сравнивают большие блоки JSON с помощью фреймворка под названием JsonUnit.
Когда тест не проходит, обычно это всего лишь несколько строк в JSON длиной более 1000 строк. Фреймворк JsonUnit даст мне точные разделы JSON, которые не прошли проверку, вот так:
но: JSON-документы различаются:
Найденно различие в узле “sent[0].acknowledgedTime”, ожидалось
<“09:56:22.216213”>, но было.Найденно различие в узле “sent[0].reopeningNumber”, ожидалось
<“RA”>, но было <“RU”>.Найденно различие в узле “sent[0].sentTime”, ожидалось
<“09:55:42.776926”>, но было <“09:55:53.901321”>.Найденно различие в узле “sent[0].value”, ожидалось <1.0E+8>, но
было <2.0E+10>.Найденно различие в узле “sent[0].volume”, ожидалось <10000>, но
было <30000>.
У меня также есть большие CSV длиной более 1000 строк, которые я хочу сравнить в тесте Junit. Если есть ошибка, я хочу, чтобы он дал мне точную строку(ы), которые не прошли проверку. Существует ли фреймворк для CSV, подобный JsonUnit?
Я просто прочитала бы CSV-документ в список строк и затем использовала бы AssertJ
assertThat(currentCsvAsLines)
.contains("some, example, line");
Ответ или решение
Чтобы сравнивать CSV файлы в JUnit тестах и получать детальную информацию о местах, где происходят ошибки, вы можете воспользоваться библиотекой Apache Commons CSV
для чтения CSV файлов и использовать AssertJ
для проверки значений. Хотя нет прямого аналога JsonUnit для CSV, вы можете создать свою обертку, которая будет предоставлять информацию о различиях на уровне строк.
Вот пошаговое решение, как вы можете реализовать это:
- Добавьте зависимости в ваш проект: В файле
pom.xml
для Maven добавьте следующие зависимости:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.8</version> <!-- Убедитесь, что используете актуальную версию -->
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.21.0</version> <!-- Актуальная версия AssertJ -->
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version> <!-- Актуальная версия JUnit -->
</dependency>
- Создайте функцию для чтения CSV файла: С помощью
Apache Commons CSV
создайте метод для считывания CSV файла в список строк.
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class CsvUtils {
public static List<String[]> readCsv(String filePath) throws IOException {
List<String[]> records = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
Iterable<CSVRecord> csvRecords = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(reader);
for (CSVRecord csvRecord : csvRecords) {
String[] record = new String[csvRecord.size()];
for (int i = 0; i < csvRecord.size(); i++) {
record[i] = csvRecord.get(i);
}
records.add(record);
}
}
return records;
}
}
- Создайте тест на сравнение CSV файлов: Используйте
AssertJ
для сравнения строк из двух CSV файлов.
import org.assertj.core.api.Assertions;
import org.junit.Test;
import java.io.IOException;
import java.util.List;
public class CsvComparisonTest {
@Test
public void compareCsvFiles() throws IOException {
List<String[]> expected = CsvUtils.readCsv("path/to/expected.csv");
List<String[]> actual = CsvUtils.readCsv("path/to/actual.csv");
Assertions.assertThat(actual).hasSameSizeAs(expected);
for (int i = 0; i < expected.size(); i++) {
String[] expectedRow = expected.get(i);
String[] actualRow = actual.get(i);
if (!Assertions.assertThat(actualRow).isEqualTo(expectedRow)) {
Assertions.fail("Различия найдены на строке " + (i + 1) + ". Ожидалось: " + String.join(", ", expectedRow) +
" но было: " + String.join(", ", actualRow));
}
}
}
}
Объяснение решения:
- Чтение CSV: Мы читаем CSV файл с помощью
Apache Commons CSV
, загружая каждую строку в массив строк. - Сравнение: Мы сравниваем количество строк между двумя файлами. Если они не равны, это сразу вызывает ошибку. Для каждой строки сравниваются значения, и если они не равны, выводается детальная информация о строке, включая ожидаемую и фактическую строки.
Таким образом, используя предложенный подход, вы получите функциональность, аналогичную той, что предоставляет JsonUnit для JSON, но для CSV, с четким указанием на ошибки и соответствующими строками.