Eqbal
Eqbal

Reputation: 4880

JUnit 4 compare Sets

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

Upvotes: 124

Views: 131779

Answers (11)

MaRK MOrev
MaRK MOrev

Reputation: 1

containsInAnyOrder() - help me.

Upvotes: -2

Yusuf BESTAS
Yusuf BESTAS

Reputation: 194

You can do it like that ->
assertThat(actualSet).containsExactlyInAnyOrder(expectedSet);

Upvotes: 0

Roman
Roman

Reputation: 66156

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);  
}  

Upvotes: 2

Bill the Lizard
Bill the Lizard

Reputation: 405735

You can assert that the two Sets are equal to one another, which invokes the Set equals() method.

public class SimpleTest {

    private Set<String> setA;
    private Set<String> setB;

    @Before
    public void setUp() {
        setA = new HashSet<String>();
        setA.add("Testing...");
        setB = new HashSet<String>();
        setB.add("Testing...");
    }

    @Test
    public void testEqualSets() {
        assertEquals( setA, setB );
    }
}

This @Test will pass if the two Sets are the same size and contain the same elements.

Upvotes: 124

FLUXparticle
FLUXparticle

Reputation: 1183

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;

Upvotes: 3

Dr. Hans-Peter St&#246;rr
Dr. Hans-Peter St&#246;rr

Reputation: 25976

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.

Upvotes: 1

Dr. Hans-Peter St&#246;rr
Dr. Hans-Peter St&#246;rr

Reputation: 25976

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.)

Upvotes: -1

Matt Friedman
Matt Friedman

Reputation: 1563

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.

Upvotes: 48

jayunit100
jayunit100

Reputation: 17648

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"/>

Upvotes: 4

user3458
user3458

Reputation:

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.

Upvotes: 7

dfa
dfa

Reputation: 116314

with hamcrest:

assertThat(s1, is(s2));

with plain assert:

assertEquals(s1, s2);

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

Upvotes: 16

Related Questions