Java 单元测试中的HashSet

Java 单元测试中的HashSet,java,junit,hashset,Java,Junit,Hashset,我有很多方法返回HashSet。我希望我的单元测试检查这些对象的状态,即确认someObject.getName()==“foobar” 但是,hashset迭代器顺序不能保证,因此我的单元测试有时会失败。我如何为这样的东西编写单元测试 例如: @测试 public void testRowsToBeRead(){ HashSet rows=newsomeobject().read(); assertEquals(19,rows.size()); 对于(Somer对象:行){ //如何确认内容?

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

但是,hashset迭代器顺序不能保证,因此我的单元测试有时会失败。我如何为这样的东西编写单元测试

例如:

@测试
public void testRowsToBeRead(){
HashSet rows=newsomeobject().read();
assertEquals(19,rows.size());
对于(Somer对象:行){
//如何确认内容?
}
}
我想我可能太快就接受了答案


我现在遇到的问题是,我已经实现了equals方法,它在每个设计中只检查对象中的2个字段(它模仿DB表)。
然而,在我的单元测试中,我想检查所有字段,如description等,这些字段不在我的equals中。因此,如果两个字段被交换,而这些字段不在我的equals实现中,那么单元测试将给出一个假阳性。

您可以使用
LinkedHashSet
来保证顺序。

我的方法:

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
equals
可能是这样的,它只检查
field1

@Override
public boolean equals(Object other) {
    return this.getField1().equals( ((SomeObject) other).getField1() );
}
毫无疑问,这取决于您的具体用例,可能会变得更加复杂。希望这有助于…

尝试使用以下资产:

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

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


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

我建议使用
HashSet.equals(Object)

JavaDoc说:

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

所以我认为“家”的“选择2”就足够了


另外:虽然HashSet不能保证顺序,但是相等的HashSet的顺序和大小是相同的。

equals
hashCode
必须正确实现才能使用这种方法(并使用HashSet)。我已经有equals和hashCode单元测试了,所以我想这正是我想要的。难道HashSet#equals不会也这样做吗?也就是说,
如果(!expcectedRows.equals(rows)){/*fail*/}
@Arturs Licis:+1,根据JavaDOc,您是对的,它的行为应该是相同的。。。保存了四行代码:-)我现在遇到的问题是,我实现了equals方法,它在每个设计中只检查对象中的两个字段(它模仿DB表)。然而,在我的单元测试中,我想检查所有字段,如description等,这些字段不在我的equals中。因此,如果两个字段被交换,而这些字段不在我的equals实现中,那么单元测试将给出一个假阳性。谢谢。这需要我改变实际的方法。我可能会在将来某个时候这样做,但现在我只是想让我的单元测试继续下去。
@Override
public boolean equals(Object other) {
    return this.getField1().equals( ((SomeObject) other).getField1() );
}
Assert.assertThat(r.getName(), AnyOf.anyOf(Is.is("foobar1"), Is.is("foobar2"), ...));