В статье о тестировании параметров при помощи EasyMock рассказывалось про использование матчеров аргументов, позволяющих гибко описывать входные параметры вызываемых из тестируемого кода методов, а также приводился их список. Разумеется, список матчеров не конечный и EasyMock допускает разработку собственных матчеров.
Предположим, что мы разрабатываем систему, которая записывает какие-либо заказы пользователей для выполнения на какой-то день в будущем, причём день этот задаётся, например, уровнем пользователя. Заказ для одного класса пользователей выполняется на следующий день, для другого через три дня. И мы хотим протестировать метод, сохраняющий заказы с добавлением дней:
1 2 3 4 5 6 7 | /** * Create order, that will be completed tomorrow. * @param u Order owner. */ final void addOrder(User u) { orderRepository.addOrder(u, LocalDate.now().plusDays(1)); } |
Разумеется, можно просто захватить аргумент addOrder() и проверить корректно задания даты. Однако это требует достаточно большого количества кода и если вызовов таких много, то можно сделать и свой матчер, для повышения читаемости тестов.
Матчеры реализуют интерфейс IArgumentMatcher, который имеет два метода: matches(), выполняющий непосредственную проверку, и appendTo() добавляющий данные о матчере в строковый буфер, чтобы было что показать пользователю. Кроме того, рекомендуется сделать статический метод, для облегчения использования матчера.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | public class FutureEquals implements IArgumentMatcher { private final long daysInFuture; public FutureEquals(final long d) { this.daysInFuture = d; } @Override public boolean matches(Object argument) { if (!(argument instanceof LocalDate)) { return false; } LocalDate actual = (LocalDate) argument; return LocalDate.now().plusDays(daysInFuture).getDayOfYear()==actual.getDayOfYear(); } @Override public void appendTo(StringBuffer buffer) { buffer.append("eqFuture("); buffer.append(LocalDate.now().plusDays(daysInFuture)); buffer.append(")"); } public static LocalDate eqFuture(long expected) { EasyMock.reportMatcher(new FutureEquals(expected)); return null; } } |
Использование такого матчера очевидно, и не отличается от использования других матчеров:
1 2 3 4 5 6 7 | @Test public void testTomorrow() { orderRepository.addOrder(eq(testUser()), eqFuture(1)); EasyMock.replay(orderRepository); testedObject.addOrder(testUser()); } |
Код примера доступен на github.