With the returns method in AssertJ we can verify an object using a function. This allows us to verify an object in a very flexible way. We can chain multiple returns method calls to verify multiple aspects of our object. The first argument of the returns method is the expected value of the function call. And the second argument is a function that calls a method on the object we want to verify. A simple function call would be a method reference using the class of the object. But we can also write our own function, where the argument of the function is actual object we are writing the assertion for. To verify the function doesn’t return an expected value we can use the method doesNotReturn.
We can also pass the function to the from method, available in the Assertions class. It can make the assertion more readeable as we can now read the code as: we expect the following value from calling this function.

In the following example we use the returns and doesNotReturn methods in several use cases:

package mrhaki;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.from;

class Returns {

    // Pirate record we will use for tests.
    record Pirate(String name, String ship, int age) {}

    void checkReturnValueMethodReference() {
        // With returns() we can specify the expected value
        // from a function call.
        // We can use a method references to easily
        // get a return value we want to verify.
        assertThat(new Pirate("Jack Sparrow", "Black Pearl", 40))
                .returns("Jack Sparrow", Pirate::name)
                .returns("Black Pearl", Pirate::ship)
                .returns(40, Pirate::age);

    void checkValueIsNotReturned() {
        // Instead of using returns() we can use doesNotReturn()
        // to verify the function doesn't return an expected value.
        assertThat(new Pirate("Will Turner", "Flying Dutchman", 35))
                .doesNotReturn("Jack Sparrow", Pirate::name)
                .doesNotReturn("Black Pearl", Pirate::ship)
                .doesNotReturn(40, Pirate::age);

    void checkReturnValueFrom() {
        // We can use the Assertions.from() method to add
        // some readability to our assertions.
        // We simply pass the function that should return our
        // expected value to the from() method.
        assertThat(new Pirate("Jack Sparrow", "Black Pearl", 40))
                .returns("Jack Sparrow", from(Pirate::name))
                .returns("Black Pearl", from(Pirate::ship))
                .returns(40, from(Pirate::age));

    void checkReturnValueFromFunction() {
        // Instead of using method references as functions
        // like in the first test,
        // we can use custom functions as well.
        // The type of the function argument is the object
        // we write the assertions for.
        assertThat(new Pirate("Jack Sparrow", "Black Pearl", 40))
                .returns(true, p -> p.name().startsWith("Jack"))
                .returns("black-pearl", p -> p.ship().toLowerCase().replace(" ", "-"))
                // We can also from() here.
                .returns(12, from(p -> p.name().length()))
                .returns(false, p -> p.age() > 50);

Written with AssertJ 3.24.2.