My use case is that I am writing a document parser (for ReqIF documents) and want to compare that the parsed object contains the expected elements. For this, I want to write a JUnit Test.
Effectively, what I am looking for is an assertion method that compares two lists of objects with values and passes when both lists contain (in any order) objects that have the same values as the reference list.
To abstract that, consider this example:
Apple referenceApple1 = new Apple(id=1); Apple referenceApple2 = new Apple(id=2); Apple parsedApple1 = new Apple(id=1); Apple parsedApple2 = new Apple(id=2); Apple badApple = new Apple(id=3); List<Apple> referenceList = new List<Apple>(referenceApple1, referenceApple2); List<Apple> correctlyParsedList1 = new List<Apple>(parsedApple1, parsedApple2); List<Apple> correctlyParsedList2 = new List<Apple>(parsedApple2, parsedApple1); List<Apple> wronglyParsedList1 = new List<Apple>(parsedApple1, badApple); List<Apple> wronglyParsedList2 = new List<Apple>(parsedApple1, parsedApple2, parsedApple1); List<Apple> wronglyParsedList3 = new List<Apple>(parsedApple2, parsedApple2);
I am looking for an assertion method that passes when comparing any of the above
correctlyParsedList* with the
referenceList, but fails when comparing any of the above
wronglyParsedList* with the
Currently, the closest I’ve gotten to is this:
However, that will fail as soon as the objects are in another order.
//Will fail, but I want a method that will compare these and pass assertEquals(referenceList.toString(), correctlyParsedList2.toString())
Notably, the following will also fail since the Apples, while containing the same values, are not instances of the same object:
assertThat(correctlyParsedList1, is(referenceList)); //Throws This error: java.lang.AssertionError: Expected: is <[[id=1], [id=2]]> but: was <[[id=1], [id=2]]>
Is there a simple way to make such an assertion in JUnit? I know I could write a custom assertion method for this iterating over the objects, but somehow it feels like this would be a common use case that should have a pre-defined assertion method that throws expressive assertion errors.
If you do not care for the order of the elements, you can sort the lists before comparing them.
You should use
containsAll to check whether one list has all items from another, as long as you have proper equals implementation for your
Apple this should work:
// Covers case where all items that are from correct list are in reference as well // but also some additional items exist that are not in correct list assertEquals(correctlyPassedList.size(), referenceList.size()); // Checks if each element is contained in list assertTrue(referenceList.containsAll(correctlyPassedList));
Also another solution might be to sort both lists (this might be better in case of really long lists) and then simply check like this: