[java] JUnit 4 compare Sets

How would you succinctly assert the equality of Collection elements, specifically a Set in JUnit 4?

This question is related to java unit-testing collections junit

The answer is


I like the solution of Hans-Peter Störr... But I think it is not quite correct. Sadly containsInAnyOrder does not accept a Collection of objetcs to compare to. So it has to be a Collection of Matchers:

assertThat(set1, containsInAnyOrder(set2.stream().map(IsEqual::equalTo).collect(toList())))

The import are:

import static java.util.stream.Collectors.toList;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertThat;

Using Hamcrest:

assertThat( set1, both(everyItem(isIn(set2))).and(containsInAnyOrder(set1)));

This works also when the sets have different datatypes, and reports on the difference instead of just failing.


with hamcrest:

assertThat(s1, is(s2));

with plain assert:

assertEquals(s1, s2);

NB:t the equals() method of the concrete set class is used


Check this article. One example from there:

@Test  
public void listEquality() {  
    List<Integer> expected = new ArrayList<Integer>();  
    expected.add(5);  

    List<Integer> actual = new ArrayList<Integer>();  
    actual.add(5);  

    assertEquals(expected, actual);  
}  

If you want to check whether a List or Set contains a set of specific values (instead of comparing it with an already existing collection), often the toString method of collections is handy:

String[] actualResult = calltestedmethod();
assertEquals("[foo, bar]", Arrays.asList(actualResult).toString());

List otherResult = callothertestedmethod();
assertEquals("[42, mice]", otherResult.toString());

This is a bit shorter than first constructing the expected collection and comparing it with the actual collection, and easier to write and correct.

(Admittedly, this is not a particularily clean method, and can't distinguish an element "foo, bar" from two elements "foo" and "bar". But in practice I think it's most important that it's easy and fast to write tests, otherwise many developers just won't without being pressed.)


Apache commons to the rescue again.

assertTrue(CollectionUtils.isEqualCollection(coll1, coll2));

Works like a charm. I don't know why but I found that with collections the following assertEquals(coll1, coll2) doesn't always work. In the case where it failed for me I had two collections backed by Sets. Neither hamcrest nor junit would say the collections were equal even though I knew for sure that they were. Using CollectionUtils it works perfectly.


As an additional method that is array based ... you can consider using unordered array assertions in junitx . Although the Apache CollectionUtils example will work, there is a pacakge of solid assertion extensions there as well :

I think that the

ArrayAssert.assertEquivalenceArrays(new Integer[]{1,2,3}, new Integer[]{1,3,2});

approach will be much more readable and debuggable for you (all Collections support toArray(), so it should be easy enough to use the ArrayAssert methods.

Of course the downside here is that, junitx is an additional jar file or maven entry...

 <dependency org="junit-addons" name="junit-addons" rev="1.4"/>

A particularly interesting case is when you compare

   java.util.Arrays$ArrayList<[[name,value,type], [name1,value1,type1]]> 

and

   java.util.Collections$UnmodifiableCollection<[[name,value,type], [name1,value1,type1]]>

So far, the only solution I see is to change both of them into sets

assertEquals(new HashSet<CustomAttribute>(customAttributes), new HashSet<CustomAttribute>(result.getCustomAttributes()));

Or I could compare them element by element.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to unit-testing

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0 How to test the type of a thrown exception in Jest Unit Tests not discovered in Visual Studio 2017 Class Not Found: Empty Test Suite in IntelliJ Angular 2 Unit Tests: Cannot find name 'describe' Enzyme - How to access and set <input> value? Mocking HttpClient in unit tests Example of Mockito's argumentCaptor How to write unit testing for Angular / TypeScript for private methods with Jasmine Why is the Visual Studio 2015/2017/2019 Test Runner not discovering my xUnit v2 tests

Examples related to collections

Kotlin's List missing "add", "remove", Map missing "put", etc? How to unset (remove) a collection element after fetching it? How can I get a List from some class properties with Java 8 Stream? Java 8 stream map to list of keys sorted by values How to convert String into Hashmap in java How can I turn a List of Lists into a List in Java 8? MongoDB Show all contents from all collections Get nth character of a string in Swift programming language Java 8 Distinct by property Is there a typescript List<> and/or Map<> class/library?

Examples related to junit

Eclipse No tests found using JUnit 5 caused by NoClassDefFoundError for LauncherFactory How to resolve Unneccessary Stubbing exception JUnit 5: How to assert an exception is thrown? How do I mock a REST template exchange? Class Not Found: Empty Test Suite in IntelliJ Unable to find a @SpringBootConfiguration when doing a JpaTest Failed to load ApplicationContext (with annotation) Example of Mockito's argumentCaptor Mockito - NullpointerException when stubbing Method Spring jUnit Testing properties file