How to Junit Test That Two List<E> Contain the Same Elements in the Same Order

How to JUnit test that two List<E> contain the same elements in the same order?

I prefer using Hamcrest because it gives much better output in case of a failure

Assert.assertThat(listUnderTest, 
IsIterableContainingInOrder.contains(expectedList.toArray()));

Instead of reporting

expected true, got false

it will report

expected List containing "1, 2, 3, ..." got list containing "4, 6, 2, ..."

IsIterableContainingInOrder.contain

Hamcrest

According to the Javadoc:

Creates a matcher for Iterables that matches when a single pass over the examined Iterable yields a series of items, each logically equal to the corresponding item in the specified items. For a positive match, the examined iterable must be of the same length as the number of specified items

So the listUnderTest must have the same number of elements and each element must match the expected values in order.

Compare 2 List<String> if they contain same elements in any order [JUnit - Asset]

You can first sort both the List and then compare the sorted Lists.

List<String> list1 = Arrays.asList("a","b","c");
List<String> list2 = Arrays.asList("c","a","b",);
Collections.sort(list1);
Collections.sort(list2);
assertEquals( list1, list2 ); // true

Test List<List<T>> contains the same items in any order

The method .containsAll() works for a Collection not for a Collection of Collection.

Basically I ended up comparing each elements of the first collection, then use .containsAll() for the nested collection.

import org.junit.Assert;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;

@Test
public void groupAnagramsTest() {
List<List<String>> expectedResult = Arrays.asList(Arrays.asList("bat"), Arrays.asList("nat", "tan"), Arrays.asList("ate", "eat", "tea"));
List<List<String>> result = Arrays.asList(Arrays.asList("bat"), Arrays.asList("tan", "nat"), Arrays.asList("tea", "eat", "ate"));

// to test the equality without order,
// assert that all elements are contained in the compared list and vice versa
for (int i = 0; i < result.size(); i++) {
Assert.assertTrue(expectedResult.get(i).containsAll(result.get(i)));
Assert.assertTrue(result.get(i).containsAll(expectedResult.get(i)));
}
}

NOTE: the order of the outer List is the same between the two. Otherwise it won't work.

Junit: How to check if 2 collections are equals with elements in different order?

To check equality of two collections, the size of the two collections should be compared, next a difference may be calculated by removing elements in collection c2 from the copy of collection c1 and if it's empty the collections are equal:

public static <T> boolean areCollectionsEqual(Collection<T> c1, Collection<T> c2) {
if (c1 == c2) return true;

if (c1 == null || c2 == null || c1.size() != c2.size()) {
return false;
}

Collection<T> tmp = new ArrayList<>(c1);
for (T item : c2) {
if (!tmp.remove(item)) {
return false;
}
}

return tmp.isEmpty();
}

Such method allows to compare different types of collections (e.g. List to Set)

Then common assertTrue / assertFalse may be used in tests:

public static <T> void assertCollectionsAreEqual(Collection<T> expected, Collection<T> actual, String message) {
Assertions.assertTrue(areCollectionsEqual(expected, actual), message);
}

public static <T> void assertCollectionsAreNotEqual(Collection<T> expected, Collection<T> actual, String message) {
Assertions.assertFalse(areCollectionsEqual(expected, actual), message);
}

Update Collection::removeAll may produce incorrect result in the case when the collections contain the same elements with different frequencies. e.g. List.of (1, 2, 2, 2) and List.of (1, 2, 1, 2), so it was replaced with iterative remove.

AssertEquals 2 Lists ignore order

As you mention that you use Hamcrest,

So I would pick one of the collection Matchers

import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
import static org.junit.Assert.assertThat;

public class CompareListTest {

@Test
public void compareList() {
List<String> expected = Arrays.asList("String A", "String B");
List<String> actual = Arrays.asList("String B", "String A");

assertThat("List equality without order",
actual, containsInAnyOrder(expected.toArray()));
}

}

Assert that the two lists have the same length. Create a list of all names and surnames

I assume you don't need a specific order in the result list of names and surnames.
I would recommend to remove use of streams:

static List<String> ex2(List<String> names, List<String> surnames) {
if (names.size() != surnames.size()) {
throw new IllegalArgumentException("the two lists are not the same length");
}
List<String> namesAndSurnames = new ArrayList<>(names);
namesAndSurnames.addAll(surnames);
return namesAndSurnames;
}

How to compare two lists of double in JUnit

I think the right solution here would be a Custom Matcher. Basically something like IsIterableContainingInOrder that only works on Doubles and supports an error margin.

JUnit Test that ArrayList elements aren't duplicates

In fact you have to assert more than that.

To check the actual behavior of the method, you should indeed assert from the returned list that :

  • the list has the expected size

Assert.assertEquals(size, list.size());

  • the list doesn't contain dup

Assert.assertEquals(new HashSet<Long>(list).size(), actualList.size());

  • the list elements are in the range min-max passed to.

for (long v : list){
Assert.assertTrue(v " + " is not in the expected range", v >= min && v <= max);
}

As M. le Rutte underlined, I would also argue that the method API would make more sense to return a Set instead of List as an order of elements is not expected : the number are random.

And as a side note, your implementation is not efficient.

With a large range and a size requested close to the range size, you could loop much more than required.



Related Topics



Leave a reply



Submit