Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assert that two Lists<String> are equal, ignoring order

Tags:

java

assertj

I am using AssertJ and I am trying to assert that two List<String> contain same strings, ignoring the order.

List<String> expected = Arrays.asList("Something-6144-77.pdf", "d-6144-77.pdf", "something-6144-78.pdf", "Something-6144-8068.pdf");
List<String> actual = new ArrayList<String>();

assertThat(actual.size()).isEqualTo(expected.size());

// This line gives the error: "The method containsExactlyInAnyOrder(String...) in the type ListAssert<String> is not applicable for the arguments (List<String>)"
assertThat(actual).containsExactlyInAnyOrder(expected);

How can I fix the compilation error below that is appearing when trying to use containsExactlyInAnyOrder()?

"The method containsExactlyInAnyOrder(String...) in the type ListAssert is not applicable for the arguments (List)"

like image 537
Catfish Avatar asked Mar 27 '17 20:03

Catfish


People also ask

How do you assert two lists are equal?

sort() coupled with == operator can achieve this task. We first sort the list, so that if both the lists are identical, then they have elements at the same position.

How do you check if two lists of strings are equal in Java?

List equals() Method in Java with Examples. This method is used to compare two lists. It compares the lists as, both lists should have the same size, and all corresponding pairs of elements in the two lists are equal.

How do you assert two lists in JUnit?

Using JUnit We can use the logic below to compare the equality of two lists using the assertTrue and assertFalse methods. In this first test, the size of both lists is compared before we check if the elements in both lists are the same. As both of these conditions return true, our test will pass.

What is the difference between assertEquals and assertSame?

assertEquals() Asserts that two objects are equal. assertSame() Asserts that two objects refer to the same object. the assertEquals should pass and assertSame should fail, as the value of both classes are equal but they have different reference location.


3 Answers

Both the answers (by jlordo and by dasblinkenlight) work, but are workarounds rather than the correct way to do it.

There is a method in the AssertJ library for specifically checking if a List contains all values, regardless of order, in another Iterable. It is called containsOnlyElementsOf():

public SELF containsOnlyElementsOf(Iterable<? extends ELEMENT> iterable)

Same semantic as ObjectEnumerableAssert.containsOnly(Object[]) : verifies that actual contains all the elements of the given iterable and nothing else, in any order.

Example :

Iterable<Ring> rings = newArrayList(nenya, vilya);

// assertion will pass
assertThat(rings).containsOnlyElementsOf(newLinkedList(nenya, vilya)) .containsOnlyElementsOf(newLinkedList(nenya, nenya, vilya, vilya));

// assertion will fail as actual does not contain narya
assertThat(rings).containsOnlyElementsOf(newLinkedList(nenya, vilya, narya));
// assertion will fail as actual contains nenya assertThat(rings).containsOnlyElementsOf(newLinkedList(vilya));

So, this method is the one you should use, like below. There is no need to cast or transform your List to an Array.

assertThat(actual).containsOnlyElementsOf(expected);

As a side note, your assertion on the size of the list is redundant:

assertThat(actual.size()).isEqualTo(expected.size());

This is already covered in the assertion that the lists contain the same elements.

Finally, if you do need to assert that a list has a specific site, AssertJ has a built-in method for this (hasSameSizeAs()):

assertThat(actual).hasSameSizeAs(expected);
like image 180
Magnilex Avatar answered Nov 07 '22 01:11

Magnilex


The error message gives you the solution:

The method containsExactlyInAnyOrder(String...)

String... is a any number of strings but can be passed as an array as well:

assertThat(actual).containsExactlyInAnyOrder((String[]) expected.toArray(new String[expected.size()]));

The cast is necessary here and that code is given under the assumption that the expected element is created different than in your example, as it doesn't make sense to convert an array to a list and back.

Here some documentation to varargs (Arbitrary number of arguments, the ...): https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html

like image 24
jlordo Avatar answered Nov 07 '22 01:11

jlordo


In newer versions of assertj there is a containsExactlyInAnyOrderElementsOf for exactly this purpose. Your example boils down to

assertThat(actual).containsExactlyInAnyOrderElementsOf(expected);
like image 5
dastrobu Avatar answered Nov 07 '22 00:11

dastrobu