Search code examples
javajunit5assertj

usingRecursiveFieldByFieldElementComparator not working


I'm stuck trying to get the second test of the code below to work.

Both have the same payload structure, the one that works use Map<> only, the second one uses classes.

Why does the first test work but the second doesn't?

It seems a bug with usingRecursiveFieldByFieldElementComparator.

package com.example.hi;

import com.example.hi.ExampleTest.Foo.Bar;
import lombok.AllArgsConstructor;
import lombok.Value;
import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;

public class ExampleTest {

    Comparator<LocalDateTime> truncateSeconds = (a, exp) ->
        a.isAfter(exp.truncatedTo(ChronoUnit.SECONDS)) ? 0 : 1;

    @Test
    void works() {

        var a = Map.of("values", Map.of("one", singletonList(Map.of("date", LocalDateTime.now()))));
        var b = Map.of("values", Map.of("one", singletonList(Map.of("date", LocalDateTime.now()))));

        assertThat(singletonList(a))
            .usingRecursiveFieldByFieldElementComparator()
            .usingComparatorForElementFieldsWithType(truncateSeconds, LocalDateTime.class)
            .containsExactly(b);
    }

    @Test
    void works_not() {

        var a = new Foo(Map.of("one", singletonList(new Bar(LocalDateTime.now()))));
        var b = new Foo(Map.of("one", singletonList(new Bar(LocalDateTime.now()))));

        assertThat(singletonList(a))
            .usingRecursiveFieldByFieldElementComparator()
            .usingComparatorForElementFieldsWithType(truncateSeconds, LocalDateTime.class)
            .containsExactly(b);
    }

    @Value
    @AllArgsConstructor
    public static class Foo {

        Map<String, List<Bar>> values;

        @Value
        @AllArgsConstructor
        public static class Bar {

            LocalDateTime date;
        }
    }
}

Solution

  • The issue has been fixed in AssertJ Core 3.17.0 and the following should work:

    // static import RecursiveComparisonConfiguration.builder
    RecursiveComparisonConfiguration configuration = builder().withIgnoreAllOverriddenEquals(true)
                                                              .withComparatorForType(truncateSeconds, LocalDateTime.class)
                                                              .build();
    
    assertThat(list).usingRecursiveFieldByFieldElementComparator(configuration)
                    .containsExactly(b);