Matchers

Из коробки JUnit предлагает некоторое количество assert* методов, позволяющих проверить состояние объекта. Но эти примитивные методы не позволяют написать комплексных проверок, например «значение эквивалентно X или является null» или «Значение объекста эквивалентно X и значение его свойства Z эквивалетно Y» итд.

В современных версиях JUnit кроме классических assert*  методом есть и особенный метод, assertThat :

Который проверяет что выражение, описанное матчерами (matchers, устоявшийся перевод, предикаты, ничем не лучше, поэтому я буду использовать кальку с английского), будучи применённым к значению, истинно:

На самом деле, JUnit использует родственный проект Hamcrest, сфокусированный на разработке универсальных матчеров. А заключается основное преимущество матчеров перед старорежимными assert* методами в том, что матчер может быть любым (до той поры, пока он следует интерфейсу) и использование матчеров позволяет декларативно описывать условия теста.

Можно написать матчер pink, проверяющий цвет и проверить цвет пантеры:

Или написать матчер, рализующий логическую операцию и проверить два свойства одним махом:

Кстати, для англоговорящих в использовании assertThat есть ещё один плюс -проверочные выражения написаны на практически разговорном языке:

 

Подготовка

Возьмём код из примера @Before/@After и скопируем класс StringUtilsTest  в StringUtilsMatcherTest

включает в себя небольшое подмножество матчеров, но полностью совместим с остальными матчерами , поэтому добавим их к проекту:

 

Тесты

В новом классе перепишем тесты с использованием матчеров:

На мой взгляд is(closeTo()) гораздо удобнее и позволяет не помнить о третьем параметре assertEquals при сравнении чисел с плавающей запятой.

Теперь массивы:

Можно забыть и о assertArrayEquals: hamcrest и assertThat достаточно умны, чтобы сравнить массивы. Нечёткое сравнение массивов прекрасно иллюстрирует возможности матчеров:

 

Исходный код примера доступен на github