Writing readable tests with AssertJ
Tags: java, assertj, testing
Published: 2019-03-29 10:46:13

---
title: Writing readable tests with AssertJ
published: true
description: 
tags: #java #assertj #testing
---

[AssertJ](http://joel-costigliola.github.io/assertj/) is a library that provides "fluent assertions for java". The fluent interface of the assertions allows developers to write very readable tests. In this article I will try to show how this can be accomplished for your own domain objects.
Let's imagine there is some kind of Validator that returns a ValidationResult. The ValidationResult could look like that:

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

```

When testing the validator the ValidationResult will be checked according to the expectations of the test. One way to describe the assertions with [AssertJ](http://joel-costigliola.github.io/assertj/) is the following.

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

```

If done like that, you do not really win something in comparison to other assertion libraries.
It is possible to have the assertion automatically generated. That would make the test code look like that.

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

```

The problem here is, that the readability can still be improved.
[AssertJ](http://joel-costigliola.github.io/assertj/) lets you write your own Assert classes for your domain objects. That means all the methods can be named the way that really readable tests can be produced. The class ValidationResultAssert could look like that.

```java
public class ValidationResultAssert extends AbstractAssert<ValidationResultAssert, ValidationResult> {

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

```

This leads to a assertion that can be read like a sentence, which makes it very easy to understand why the expectations in the test are the way they are. In addition to that a test like that also provides an explicit description of the dependencies within you domain model.

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

```

This is is a rather simple example, but as your code's complexity grows the readability of your tests gets more and more important.