Testing content of list ignoring some of the fields

22,296

Solution 1

Give a try to AssertJ's usingElementComparatorIgnoringFields:

Employee bill = new Employee("Bill", 60, "Micro$oft");
Employee appleBill = new Employee("Billie", 60, "Apple");
List<Employee> employees = newArrayList(bill, appleBill);

Employees[] expectedEmployees = { new Employee("Bill", 60, "Google"), 
                                  new Employee("Billie", 60, "Facebook") };
// this assertion succeeds as we don't compare the company field.     
assertThat(employees).usingElementComparatorIgnoringFields("company")
                     .contains(expectedEmployees);

edit: The new recursive comparison API can be used, it gives much finer control about what is being compared: https://assertj.github.io/doc/#assertj-core-recursive-comparison-ignoring-fields

Solution 2

In my case I tried to compare lists of different classes. @Joel Costigliola hinted me to use usingElementComparatorIgnoringFields, so I wrote this code:

List<ClassOne> input = new ArrayList<>();
input.add(...);
...
List<ClassTwo> result = new ArrayList<>();
...
assertThat(result).usingElementComparatorIgnoringFields("field1", "field2").isEqualTo(input);
Share:
22,296
homaxto
Author by

homaxto

Updated on July 09, 2022

Comments

  • homaxto
    homaxto almost 2 years

    I have a scenario where I receive a list from a method call and I would like to assert that the list contains the correct elements. One way to do this would be to look for some detail in each element to see which expected element to compare with - eg. a name. However the elements also contains a random generated UUID that I do not care about comparing.
    And then I thought a test tool might come to my rescue. Take the following simplified example.

    I have a class Dog:

    public class Dog {
        private String name;
        private Integer age;
    }
    

    They are contained in a list:

    List<Dog> dogs = ... many dogs
    

    Now I want to test that the list contains the expected dogs, but for some reason I do not know some of the fields - let us say age. I have tried both using assertj and hamcrest but I cannot find the correct solution that both compares two lists while also ignoring some of the fields.

    Until now this is what I have (using hamcrest):

    List<Dog> actualDogs = codeUndertest.findDogs(new Owner("Basti"));
    List<Dog> expectedDogs = createExpectedListOfDogsWithoutTheAge();
    
    Matcher.assertThat(actualDogs.get(0), Matcher.is(com.shazam.shazamcrest.matcher.Matchers
        .sameBeanAs(expectedDogs.(0))
        .ignoring("age")
    ))
    

    This works but it only compares two objects of class Dog. How do I compare all the dogs in the two list?
    Bonus question: how do I compare the lists without knowing the order or if I only need to assert that the expected dogs are contained in the list.

  • homaxto
    homaxto over 6 years
    If my expectedDogs is an array I can pass this as parameter to contains().
  • Roshana Pitigala
    Roshana Pitigala almost 6 years
    While this may answer the question it's better to include some description on how this answer my help to solve the issue.