Рубрики
Без рубрики

Написание удобочитаемых тестов с помощью Assert

AssertJ – это библиотека, которая предоставляет “плавные утверждения для java”. Плавный интерфейс утверждения… Помеченный как java, assert, testing.

AssertJ – это библиотека, которая предоставляет “плавные утверждения для java”. Плавный интерфейс утверждений позволяет разработчикам писать очень удобочитаемые тесты. В этой статье я попытаюсь показать, как это можно сделать для ваших собственных объектов домена. Давайте представим, что существует какой-то валидатор, который возвращает ValidationResult. Результат проверки может выглядеть следующим образом:

public enum ErrorCause {
    PARSE,
    RUNTIME
}

public class ValidationResult {

    private final boolean failed;
    private final ErrorCause errorCause;
    private final String message;

    public ValidationResult(boolean failed, ErrorCause errorCause, String message) {
        this.failed = failed;
        this.errorCause = errorCause;
        this.message = message;
    }

    public boolean hasFailed() {
        return failed;
    }

    public ErrorCause getErrorCause() {
        return errorCause;
    }

    public String getMessage() {
        return message;
    }
}

При тестировании валидатора результат проверки будет проверен в соответствии с ожиданиями теста. Один из способов описать утверждения с помощью AssertJ заключается в следующем.

ValidationResult result = validator.validateSomething(...);
assertThat(result.hasFailed()).isTrue();
assertThat(result.getErrorCause()).isEqualTo(ErrorCause.PARSE);
assertThat(result.getMessage()).isEqualTo("the expected message");

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

ValidationResult result = validator.validateSomething(...);
assertThat(result).isFailed().hasErrorCause(ErrorCause.PARSE).hasMessage("the expected message");

Проблема здесь в том, что читаемость все еще может быть улучшена.

public class ValidationResultAssert extends AbstractAssert {

    private  ValidationResultAssert(ValidationResult actual) {
        super(actual, ValidationResultAssert.class);
    }

    public ValidationResultAssert hasFailed() {
        Assertions.assertThat(actual.hasFailed()).isTrue();
        return this;
    }

    public ValidationResultAssert dueToAParsingError() {
        Assertions.assertThat(actual.getErrorCause()).isEqualTo(ErrorCause.PARSE);
        return this;
    }

    public ValidationResultAssert dueToCauseARuntimeError() {
        Assertions.assertThat(actual.getErrorCause()).isEqualTo(ErrorCause.RUNTIME);
        return this;
    }

    public ValidationResultAssert withTheMessage(String message) {
        Assertions.assertThat(actual.getMessage()).isEqualTo(message);
        return this;
    }

    public static ValidationResultAssert assertThat(ValidationResult actual) {
        return new ValidationResultAssert(actual);
    }
}

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

assertThat(result)
    .hasFailed()
    .dueToAParsingError()
    .withTheMessage("the expected message");

Это довольно простой пример, но по мере того, как сложность вашего кода растет, читаемость ваших тестов становится все более и более важной.

Оригинал: “https://dev.to/gossie/writing-readable-test-with-assertj-2po8”