Помогите написать Assert в цикле for

Рейтинг: -1Ответов: 2Опубликовано: 30.06.2023

Есть массив из n числа элементов, и нужно написать цикл, который бы пробегался по нему и проверял assert-ом каждый из них.

{
"total": 762,
"items": [
    {
        "id": 559881,
        "title": "...",
        "address": "",
        "imageUrl": "https://...",
        "url": "..."
    },`

Я реализовал это вот так

Assert.assertTrue {
        for (int i = 1; i < 5; i++) {
            result.getItems().get(0).getId() == 559881;
            result.getItems().get(0).getTitle().isEmpty();
            result.getItems().get(0).getAddress().isEmpty();
            result.getItems().get(0).getImageUrl().isEmpty();
            result.getItems().get(0).getUrl().isEmpty();
        }

Но видимо не хватает знаний синтаксиса чтобы это всё заработало, помогите пожалуйста это реализовать

Ответы

▲ 1Принят

Нужно не цикл в Assert.assertTrue заворачивать, а каждое условие по отдельности. Ну и брать нужно брать элемент под конкретным индексом, а не все время 0-й:

for (int i = 1; i < 5; i++) {
    Assert.assertTrue(result.getItems().get(i).getId() == 559881);
    Assert.assertTrue(result.getItems().get(i).getTitle().isEmpty());
    Assert.assertTrue(result.getItems().get(i).getAddress().isEmpty());
    Assert.assertTrue(result.getItems().get(i).getImageUrl().isEmpty());
    Assert.assertTrue(result.getItems().get(i).getUrl().isEmpty());
}

То есть, буквально то что вы написали:

нужно написать цикл, который бы пробегался по нему и проверял assert-ом каждый из них.

Через for-each-подобный синтаксис:

for (var item: result.getItems()) {
    Assert.assertTrue(item.getId() == 559881);
    Assert.assertTrue(item.getTitle().isEmpty());
    Assert.assertTrue(item.getAddress().isEmpty());
    Assert.assertTrue(item.getImageUrl().isEmpty());
    Assert.assertTrue(item.getUrl().isEmpty());
}

Лучше, конечно, где возможно использовать не assertTrue а assertEquals, например, чтобы при падении теста видно было какое именно значение не совпало.

Если в классе, который у вас в items, переопределен метод equals, где сравниваются поля, и есть toString, то в принципе можно одной строкой каждый объект проверять:

for (var item: result.getItems()) {
    Assert.assertEquals(item, new Item(559881, List.of(), List.of(), List.of(), List.of());
}
▲ 1

В JUnit5 есть подходящее семейство методов assertAll, которое можно использовать для группировки ассертов. Данные методы принимают на вход коллекцию Collection<Executable> execs, переменное число Executable ... execs или стрим исполняемых ассертов Stream<Executable>, включая варианты со строкой-заголовком.

Примерная реализация с использованием цикла:

List<Integer> expectedIds = List.of(559881, 559882, 559883, 559884, 559885);
List<Item> actualResult = result.getItems();
assertEquals(expectedIds.size(), actualResult.size()); // проверить равенство размеров
for (int i = 0, n = actualResult.size(); i < n; i++) {
    Item it = actualResult.get(i);
    assertAll("item #" + i,
        () -> assertEquals(expectedId.get(i), it.getId()),
        () -> assertTrue(it.getTitle().isEmpty()),
        () -> assertTrue(it.getAddress().isEmpty()),
        () -> assertTrue(it.getImageUrl().isEmpty()),
        () -> assertTrue(it.getImageUrl().isEmpty())
    );
} 

Ещё один вариант с заменой проверки в цикле на Stream API + assertTrue / assertAll:

int[] expectedIds = {559881, 559882, 559883, 559884, 559885};

assertAll("items",
    // сравнить массивы идентификаторов
    () -> assertArrayEquals(expectedIds, result.getItems().stream().mapToInt(Item::getId).toArray()),
    () -> assertTrue(
        result.getItems()
            .stream()
            .flatMap(it -> Stream.of(
                it.getTitle(),
                it.getAddress(),
                it.getImageUrl(),
                it.getUrl()
            ))
            .allMatch(String::isEmpty)
    )
);