Собственные матчеры аргументов

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

Предположим, что мы разрабатываем систему, которая записывает какие-либо заказы пользователей для выполнения на какой-то день в будущем, причём день этот задаётся, например, уровнем пользователя. Заказ для одного класса пользователей выполняется на следующий день, для другого через три дня. И мы хотим протестировать метод, сохраняющий заказы с добавлением дней:

    /**
     * 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() добавляющий данные о матчере в строковый буфер, чтобы было что показать пользователю. Кроме того, рекомендуется сделать статический метод, для облегчения использования матчера.

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;
    }
}

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

@Test
    public void testTomorrow() {
        orderRepository.addOrder(eq(testUser()), eqFuture(1));
        EasyMock.replay(orderRepository);


        testedObject.addOrder(testUser());
    }

Скачать код примера

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *