Проверка свойств элементов Iterable в Java: Hamcrest
Быстрый ответ
Для проверки присутствия определённого свойства у элементов Iterable
, используйте метод anyMatch
из Stream API вместе с assertThat
из библиотеки AssertJ:
import static org.assertj.core.api.Assertions.assertThat;
boolean hasProperty = StreamSupport.stream(yourIterable.spliterator(), false)
.anyMatch(item -> item.checkProperty());
assertThat(hasProperty).isTrue();
Вместо checkProperty()
вам необходимо указать условие, которому должен удовлетворять каждый элемент в Iterable
.
Применение Hamcrest для формулировки утверждений
Hamcrest облегчает формулировку утверждений в Java за счет интуитивно понятного API. Вот как можно проверить произвольное свойство внутри Iterable
:
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
List<YourObject> listOfObjects = // ...
assertThat(listOfObjects, hasItem(hasProperty("name", is("expectedValue"))));
С помощью метода hasProperty
, вы легко можете проверить, соответствует ли свойство "name" ожидаемому значению "expectedValue".
AssertJ: Грациозные утверждения на практике
AssertJ делает процесс проверки свойств элементов настолько плавным, как спокойное течение реки:
import static org.assertj.core.api.Assertions.assertThat;
List<YourObject> listOfObjects = // ...
assertThat(listOfObjects).extracting("name").contains("expectedValue");
AssertJ умело извлекает свойства "name" из объектов YourObject
, а затем метод contains
проверяет, присутствует ли указанное значение среди полученных значений.
Многоаспектные методы AssertJ
Проверка нескольких свойств с использованием кортежей
Когда вам уполне несколько свойств, функция tuple
от AssertJ становится незаменимым помощником:
assertThat(listOfObjects).extracting("name", "age")
.contains(tuple("expectedName", expectedAge));
Такой подход позволяет проверять несколько свойств сразу, делая ваш тест точным и информативным.
Утверждение без учёта порядка
Если порядок следования элементов не имеет значение, к вашим услугам метод containsExactlyInAnyOrder
из AssertJ:
assertThat(listOfObjects).extracting("name")
.containsExactlyInAnyOrder("name1", "name2", "name3");
Предотвращение потенциальных проблем
Проверка размера коллекции
Прежде всего стоит убедиться, что количество элементов в коллекции соответствует ожиданиям:
assertThat(listOfObjects).hasSize(expectedSize);
Это поможет избежать ложного положительного результата, когда проверяемое свойство присутствует, но дублируется.
Утверждения после рефакторинга
Используя ссылки на методы вместо строковых литералов, вы делаете свои утверждения менее подверженными ошибкам при рефакторинге:
assertThat(listOfObjects).extracting(YourObject::getName)
.contains("expectedValue");
Таким образом, изменения имен свойств в процессе рефакторинга не приведут к ложно-положительным результатам ваших тестов.
Визуализация
Представим, что мы ищем определённый фрукт в корзине фруктов (🧺):
🧺: [🍎, 🍋, 🍇, 🍉, 🥝]
🔍: Ищем "🍋" с свойством "жёлтый".
Мы утверждаем, что в корзине есть хотя бы один фрукт с нужным нам свойством:
Утверждение: `containsYellowFruit(🧺)` -> **True** ✅ (наш "🍋" действительно жёлтый!)
Вот таким образом, мы можем быть уверены, что в корзине есть хотя бы один жёлтый фрукт.
Потоки Java 8: Проверка свойств
Потоки (Streams) в Java 8 — это производительный и удобный инструмент для фильтрации и сопоставления элементов:
boolean hasYellowFruit = fruits.stream()
.anyMatch(fruit -> "yellow".equals(fruit.getColor()));
assertThat(hasYellowFruit).isTrue();
Лямбда-выражения помогают сделать код более компактным и понятным, облегчая его чтение.
Улучшение читаемости кода с помощью статических импортов
Сократите свой код с помощью статических импортов, особенно с библиотекой AssertJ:
import static org.assertj.core.api.Assertions.assertThat;
// Другие статические импорты...
Изучение сложных свойств
Работа со вложенными свойствами
Если нужно проникнуть в недра вложенных объектов, воспользуйтесь методом flatExtracting
:
assertThat(listOfObjects)
.flatExtracting(YourObject::getSubObjects)
.extracting(SubObject::getName)
.contains("expectedSubObjectName");
Проверка нескольких условий одновременно
Чтобы проверить сразу несколько условий, можно использовать метод allSatisfy
от AssertJ:
assertThat(listOfObjects).allSatisfy(object -> {
assertThat(object.getName()).isNotEmpty();
assertThat(object.getAge()).isGreaterThan(18);
});