JUnit 4比较集


Answers:


103

您可以断言两个Sets彼此相等,这将调用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 );
    }
}

@Test如果两个将传递Sets为相同的大小和包含相同的元素。


7
这不会在报告中显示非常好的结果。如果您清楚地定义了toString,那就更好了,但还是不好(有细微的差别最终可能会导致一页文本)
Bill K

嗯,我怎么会得到:java.lang.AssertionError:预期:java.util.Hashtable <{CompanyName = 8PKQ9va3nW8pRWb4SjPF2DvdQDBmlZ,Ric = sZwmXAdYKv,Category = AvrIfd,QuoteId = 4342740204922826921}>但是是:java {util。 = 8PKQ9va3nW8pRWb4SjPF2DvdQDBmlZ,Ric = sZwmXAdYKv,类别= AvrIfd,QuoteId = 4342740204922826921}>
Giovanni Botta

3
@Giodude你有equalshashCode中,你是在为你散列表存储类中实现?
比尔蜥蜴

如您所见,这些只是字符串,而且很长...我正在测试Avro对地图进行序列化和反序列化,这就是结果。我认为必须对字符串进行序列化和反序列化的方式有些麻烦,这会使测试失败,但是我似乎找不到问题。
Giovanni Botta

即使我正在比较两个HashSet <Long>,它也对我不起作用。@MattFriedman答案实际上适用于我的用例。
bluecollarcoder 2014年

46

Apache Commons再次获救。

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

奇迹般有效。我不知道为什么,但是我发现以下内容assertEquals(coll1, coll2)并不总是有效。在我失败的情况下,我有两个由Sets支持的收藏。hamcrest和junit都不会说这些收藏是平等的,即使我确信它们是相等的。使用CollectionUtils可以完美地工作。


20
这实际上是微不足道的,棘手的部分是向呼叫者清楚表明差异
Bill K

1
接受的答案对于原始问题(专门针对两个Set的单元测试)是一个很好的答案,但是对于最一般的情况,我认为CollectionUtils的答案是更好的答案。除非使用CollectionUtils,否则我无法比较Collection和Set。
杰伊

16

hamcrest

assertThat(s1, is(s2));

用简单的断言:

assertEquals(s1, s2);

注意:使用具体集合类的equals()方法


1
我喜欢这种方法,因为Hamcrest随JUnit 4一起提供,因此不需要其他库。
JRSofty

2
当集合具有不同类型时,这可能不起作用。
汉斯·彼得·斯托尔

7

比较有趣的情况是

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

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

到目前为止,我看到的唯一解决方案是将它们都更改为集合

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

或者我可以逐个元素比较它们。


实际上,其他答案中提供了几种解决方案。无论如何,集合有点不幸,因为它们忽略了顺序。也许是ArrayList?
汉斯·彼得·斯特尔

4

作为基于数组的附加方法,您可以考虑在junitx中使用无序数组断言。尽管可以使用Apache CollectionUtils示例,但是那里也有一些可靠的断言扩展:

我认为

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

这种方法对您来说更具可读性和可调试性(所有Collections都支持toArray(),因此使用ArrayAssert方法应该足够容易。

当然,这里的缺点是,junitx是附加的jar文件或maven条目...

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

2

检查这篇文章。那里的一个例子:

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

简短但很棒的链接,非常快速地解释了如何使用Junit4-可以做什么
Johannes

1
链接断开。您是否有机会在网上找到存档版本或总结其内容?
pzp

1

使用Hamcrest:

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

当集合具有不同的数据类型时,这也适用,并且报告差异而不只是失败。


2
isIn的导入内容是什么?IntelliJ无法使用任何hamcret软件包解决导入问题。
fabien

0

如果要检查列表或集合是否包含一组特定值(而不是将其与现有集合进行比较),则通常使用集合的toString方法很方便:

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

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

这比首先构造期望的集合并将其与实际集合进行比较要短一些,并且更容易编写和更正。

(不可否认,这不是一种特别干净的方法,不能将元素“ foo,bar”与两个元素“ foo”和“ bar”区分开。但是实际上,我认为最重要的是,编写测试要容易且快速,否则,许多开发人员都不会被迫。)


这使得单元测试的结果取决于list中toString的实现。如果他们决定更改格式,则单元测试将不再起作用。我认为这不安全。
Laurens Op't Zandt

@ LaurensOp'tZandt您的意思是Oracle更改了Collection.toList()的格式?那肯定不会发生。但是,您说的不是特别干净。但实际上,我的印象是,编写测试非常容易,这是最重要的。
汉斯·彼得·斯托尔

我同意,我认为toString方法不太可能出现。因此可能它将继续工作。我只想指出这不是一种很干净的方法。但是确实很容易。出现的一个问题是比较集合时。由于不能保证其顺序。
Laurens Op't Zandt

0

我喜欢Hans-PeterStörr的解决方案...但是我认为这不太正确。可悲的containsInAnyOrder是不接受Collectionobjetcs进行比较。因此,它必须是一个CollectionMatcherS:

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

导入是:

import static java.util.stream.Collectors.toList;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertThat;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.