Skip to content

Custom representation ignored when describing expected items not in the actual list #3646

@heemskerkerik

Description

@heemskerkerik

Describe the bug
When using a custom representation for a particular class, it’s ignored when I assert equality on collections of them, specifically when collection order is ignored.

Specifically, the representation is used correctly when writing out the actual and expected values, but when the missing items are described, the regular toString() representation is used.

  • assertj core version: 3.26.3
  • java version: 17
  • test framework version: JUnit 5.10.3

Test case reproducing the bug

Add a test case showing the bug that we can run

import org.assertj.core.api.Assertions;
import org.assertj.core.presentation.StandardRepresentation;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.util.List;

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

class RepresentationTest {
    public class Item {
        private final String name;
        private final int quantity;

        public Item(String name, int quantity) {
            this.name = name;
            this.quantity = quantity;
        }

        public String getName() {
            return name;
        }

        public int getQuantity() {
            return quantity;
        }
    }

    @BeforeAll
    static void setupAll() {
        Assertions.useRepresentation(new StandardRepresentation() {
            {
                registerFormatterForType(
                    Item.class,
                    item -> String.format(
                        "Item(%s, %d)",
                        item.getName(),
                        item.getQuantity()
                    )
                );
            }
        });
    }

    @Test
    void testRepresentation() {
        List<Item> expectedItems = List.of(
            new Item("Shoes", 2),
            new Item("Pants", 3)
        );
        List<Item> actualItems = List.of(
            new Item("Pants", 3),
            new Item("Loafers", 1)
        );

        StandardRepresentation representation = new StandardRepresentation() {
            {
                registerFormatterForType(
                    Item.class,
                    item -> String.format(
                        "Item(%s, %d)",
                        item.getName(),
                        item.getQuantity()
                    )
                );
            }
        };

        assertThatExceptionOfType(AssertionError.class)
            .isThrownBy(() -> {
                assertThat(actualItems)
                    .withRepresentation(representation)
                    .usingRecursiveComparison()
                    .ignoringCollectionOrder()
                    .isEqualTo(expectedItems);
            })
            .withMessageNotContaining("RepresentationTest$Item");

    }
}

Current, the isEqualTo outputs the following:

java.lang.AssertionError: 
Expecting actual:
  [Item(Pants, 3), Item(Loafers, 1)]
to be equal to:
  [Item(Shoes, 2), Item(Pants, 3)]
when recursively comparing field by field, but found the following difference:

Top level actual and expected objects differ:
- actual value  : [Item(Pants, 3), Item(Loafers, 1)]
- expected value: [Item(Shoes, 2), Item(Pants, 3)]
The following expected elements were not matched in the actual List12:
  [RepresentationTest$Item@1e802ef9]

I would expect that last line to read [Item(Shoes, 2)].

Metadata

Metadata

Labels

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions