2

I feel like I'm missing something obvious here, but the documentation is letting me down. I'm attempting to compare two maps while ignoring a set of fields in assertJ. I would like to see this assert pass:

  private static final String[] IGNORED_FIELDS = { "ignored", "another" };
  private static final Map<String, Object> TEST_PAYLOAD = ImmutableMap.of("test", "payload", "example", "value", "ignored", "field");
  private static final Map<String, Object> COMPARISON_PAYLOAD = ImmutableMap.of("test", "payload", "example", "value", "another", "ignored field");
  // assert fails
  assertThat(TEST_PAYLOAD).isEqualToIgnoringGivenFields(COMPARISON_PAYLOAD, IGNORED_FIELDS);

However, the comparison that actually occurs is of the map objects, and fails on things like size, modCount, threshold, etc. In addition, it doesn't actually ignore the fields listed when comparing tables, keys, and values. I have also tried using

  assertThat(TEST_PAYLOAD).usingRecursiveComparison().ignoringGivenFields(IGNORED_FIELDS).isEqualTo(COMPARISON_PAYLOAD);

but this failed because it attempted to compare the ignored fields. Is there an elegant solution here, or am I going to have to manually iterate through keys?

SomeGuy
  • 485
  • 3
  • 12

2 Answers2

4

ignoringGivenFields() won't work, because it's an ObjectAssert, not a MapAssert method and operates on object's properties, not map's keys, as you pointed out.

That said, I believe there's no built-in AssertJ method which you could use, but you can write your own filter method and apply it before doing equality test:

private static <V> Map<String, V> filterIgnoredKeys(Map<String, V> map) {
    return Maps.filterKeys(map, key -> !IGNORED_FIELDS.contains(key));
}
// later
assertThat(filterIgnoredKeys(TEST_PAYLOAD))
        .isEqualTo(filterIgnoredKeys(COMPARISON_PAYLOAD))

If you want the solution to be more elegant, you can experiment with your own custom assertion.

Grzegorz Rożniecki
  • 27,415
  • 11
  • 90
  • 112
  • I did end up writing my own filter with a custom filter in the end. I'd hoped that there would be an out-of-the-box solution so that I wouldn't have to maintain the code, but it's reasonable that there isn't. – SomeGuy May 12 '20 at 05:42
  • 1
    This is a bug in AssertJ RecursiveComparison which does not handle properly ignored fields for map. – Joel Costigliola Feb 03 '21 at 01:04
  • 1
    Here's the issue: https://github.com/assertj/assertj-core/issues/2115 which will be fixed in the next release (3.20.0 or 3.19.1) – Joel Costigliola Feb 03 '21 at 01:25
0

The testPayload actually contains these key-value pairs:

"test" -> "payload", 
"example" -> "value", 
"ignored" -> "field"

Comparison payload has these key-value pairs:

"test" -> "payload", 
"example" -> "value", 
"another" -> "ignored field"

That is, you need to apply .ignoringGivenFields(IGNORED_FIELDS) to both payloads to succeed. In your first attempt you removed "another" from comparison, but "ignored" remained in the test payload; and vice versa in the second attempt.

Nowhere Man
  • 19,170
  • 9
  • 17
  • 42