question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

usingRecursiveComparison() not working when Class implements Iterable

See original GitHub issue

Summary

When asserting 2 objects are equal usingRecursiveComparison(), when the class implements Iterable, seems to cause an equals check only the iterable objects, and not the parent object. Noticed this in a more complicated Class, so mocked up an example.

In the below example, the assert in the test passes, even when the objects aren’t equal. Having followed through the code during debug, it seems if the class implements Iterable, the checks for all other variables are not performed. Tested using assertj version 3.23.1.

Example

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

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

public class SomeTest {
  public static class SomeEntry {
    private String a;

    public SomeEntry(String a) {
      this.a = a;
    }
  }

  public static class SomeIterable implements Iterable<SomeEntry>{
    private final List<SomeEntry> entries = new ArrayList<>();
    private final String name;

    public SomeIterable(String name) {
      this.name = name;
    }

    @Override
    public Iterator<SomeEntry> iterator() {
      return entries.iterator();
    }
  }


  @Test
  public void test() {
    assertThat(new SomeIterable("bob")).usingRecursiveComparison().isEqualTo(new SomeIterable("dave"));
  }
}

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
linksblackmaskcommented, Oct 16, 2022

Sorry wasn’t really thinking this morning when I woke up - yes you’re right, simply checking for instanceOf Collection won’t work. Got to say this has been a proper head scratcher.

Thinking from the perspective of what should recursiveComparison mean; I think the default behaviour, especially when equality checking, is recursively assessing all feilds are equal.

A possible solution would be to have the iterables fields from the JDK be ignored by default; and for everything else, check them, and obviously throw errors if they don’t match, adding methods like:

.ignoreAllFieldsFromIterable(Class clazz) .ignoreAllFieldsFromIterableClassesIn(String package) > .ignoreFieldsFromIterable(Class clazz, String… fields)

Then as an error message give a solution. So something like "field x in class y doesn’t match expected, should this be asserted? Use method <methodName> to ignore this field or <methodName> to ignore all fields asides from the iterator in class <clazz>.

What do you think @joel-costigliola ?

Edit - The bottom method would be covered by the ignore ignoreFields() method already.

0reactions
joel-costigliolacommented, Oct 15, 2022

Checking only iterable and collection would not work if you had extended List so I feel checking if the iterable belongs to the JDK is better (but that would not cover the case where the iterable comes from a lib like Guava), I don’t think we can find a perfect check here (maybe I’m wrong).

Read more comments on GitHub >

github_iconTop Results From Across the Web

Recursive comparison api improvements · Issue #1002 - GitHub
Recursive comparison Fluent API configuration. Implements an easy to use/discover API as in: assertThat(person).usingRecursiveComparison() .
Read more >
How to compare recursively ignoring given fields using assertJ?
It doesn't work when the fields which the comparator is trying to compare are null. This is an issue when one of objects...
Read more >
AbstractObjectArrayAssert (AssertJ fluent assertions 3.22.0 API)
Same as usingRecursiveComparison() but allows to specify your own ... are not mutually comparable (even though each element type implements Comparable).
Read more >
AssertJ - fluent assertions java library - GitHub Pages
The recursive comparison mode starts after calling usingRecursiveComparison() . Here's a simple example: public class Person { String name; double height; ...
Read more >
Introduction to AssertJ - Baeldung
AssertJ is an open-source library for writing fluent and rich assertions in Java tests. This article focuses on tools available in the basic ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found