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”