JUnit 4 compare Sets

后端 未结 9 1181
-上瘾入骨i
-上瘾入骨i 2020-12-24 03:59

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

相关标签:
9条回答
  • 2020-12-24 04:40

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

    0 讨论(0)
  • 2020-12-24 04:41

    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.

    0 讨论(0)
  • 2020-12-24 04:41

    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.

    0 讨论(0)
  • 2020-12-24 04:45

    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.

    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2020-12-24 04:47

    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;
    
    0 讨论(0)
提交回复
热议问题