Всё вместе: easymock и параметризованные тесты

Paper dolls

Когда я писал статьи по JUnit, мой коллега спросил меня, а могу ли я привести пример использования продвинутого функционала JUnit, например параметризованных тестов, в дикой природе его коде, c использованием mock объектов, внедрения зависимостей итд. Пришлось показывать 🙂

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

Подготовка

Нам понадобятся пустой maven проект с JUnit, Hamcrest и EasyMock, в проекте так же будет незримо присутствовать Spring — в зависимостях его не будет, но мы предполагаем, что приложение написано с его помощью 🙂

В качестве тестируемого класса предположим, что мы написали собственный механизм авторизации, который выполняет три проверки:

  • Проверяет, что присланный пользователем авторизационный токен верный
  • Проверяет, что присланный пользователем токен приложения верный
  • Проверяет, что пользователь не превышает ограничение на количество запросов

Обычный тест

Тест противно однообразен — выставляешь поведение, проверяешь результат. И так много много раз, по два раза для каждого сравнения. Хотелось бы задание поведения не повторять регулярно, а вынести в setup() функцию, но нет: в каждом тесте оно чуть чуть отличается.

Тест с параметрами

А ведь отличаются тесты то только параметрами! Попробуем отрефакторить тест так, чтобы в нём был ровно один тестовый метод. Определим возможные варианты исполнения:

Подтоговим класс теста к использованию параметров:

И перепишем сам тест:

Класс теста почти не изменился, но зато теперь у нас один тест покрывает все возможные варианты исполнения. Или почти все — мы забыли про кидающий NPE RequestLimitingService  Что ж, костыль в коде — костыль в тесте. Немного подправим параметры:

Я добавил две строки, исполнение которых должно привести к возврату из методов RequestLimitingService null. А в тесте я сделаю подпорку под этот null:

Некрасиво конечно, ну да ладно 🙂 Проверим результаты:

Все тесты проходят 🙂

В чём же профит? Профитов несколько: класс теста не представляет собой нереально длинную портянку почти одинаковых методов, в которых можно запутаться; при изменении тестируемого кода достаточно поменять ровно один тест; из параметров сразу видно, какие значения к какому результату приводят.

Код примера доступен на github.