单元测试中的HashSet

时间:2011-08-12 15:03:14

标签: java junit hashset

我有一堆返回HashSet的方法。我希望我的单元测试检查这些对象的状态,即确认someObject.getName() == "foobar"

然而,无法保证hashset迭代器顺序,因此我的单元测试失败了一些时间。如何为这样的东西编写单元测试?

例如:

@Test
    public void testRowsToBeRead(){
        HashSet<SomeObject> rows = new SomeObject().read();
        assertEquals(19, rows.size());

        for(SomeObject r:rows){
            //How do I confirm contents?
        }
    }

我想我可能很快就会接受答案。

我现在遇到的问题是我已经实现了equals方法,它只检查每个设计对象中的2个字段(它模仿数据库表)。 但是在我的单元测试中,我想检查所有字段,如描述等,这些不在我的平等中。因此,如果交换了2个字段并且这些字段不在我的equals实现中,则单元测试会产生误报。

5 个答案:

答案 0 :(得分:4)

我的方法:

public void testRowsToBeRead(){
    HashSet<SomeObject> expectedRows = new HasSet<SomeObject();
    expectedRows.add(new SomeObject("abc"));
    expectedRows.add(new SomeObject("def"));

    HashSet<SomeObject> rows = new SomeObject().read();

    // alternative 1
    assertEquals(19, rows.size());

    for(SomeObject r:rows){
        if (!expectedRows.contains(r)) {
            // test failed
        }
    }

    // alternative 2
    assertTrue(expectedRows.equals(rows));
}

要依赖此测试,您可能需要其他单元测试,确认SomeObject的{​​{1}}和equals方法可以正常工作...

根据您的一条评论进行编辑

如果要检查不属于hashCode合同的字段,则必须遍历该集合:

equals

在上面的示例中,public void testRowsToBeRead(){ HashSet<SomeObject> expectedRows = new HasSet<SomeObject(); expectedRows.add(new SomeObject("a", "a1")); expectedRows.add(new SomeObject("b", "b1")); HashSet<SomeObject> rows = new SomeObject().read(); for(SomeObject r : rows) { SomeObject expected = expectedRows.get(r); // equals and hashCode must still match if (expected == null) { // failed } if (!expected.getField1().equals(r.getField1()) && !expected.getField2().equals(r.getField2())) { // failed } } } 的{​​{1}}可能如下所示,它只检查SomeObject

equals

毫无疑问,根据您的具体用例,这可能会变得更加复杂。希望这会有所帮助...

答案 1 :(得分:2)

您可以使用保证订单的LinkedHashSet

答案 2 :(得分:2)

尝试使用assertThat:

Assert.assertThat(r.getName(), AnyOf.anyOf(Is.is("foobar1"), Is.is("foobar2"), ...));

答案 3 :(得分:2)

您可以在几乎所有使用TestNG和JUnit的集合上使用Assert.assertEquals()。

如果您想自己滚动,请从预期的集合中删除实际集合的所有元素,并在完成后断言预期集合的大小为零。

答案 4 :(得分:0)

我建议使用HashSet.equals(Object)

JavaDoc说:

此实现首先检查指定的对象是否为此set;如果是这样,它返回true。然后,它检查指定的对象是否是一个大小与该集合的大小相同的集合;如果没有,则返回false。如果是,则返回containsAll((Collection)o)。

所以我认为“家”的“另类2”就足够了。

plus:虽然HashSet不保证订单,但是等于的HashSets的顺序和大小相同。