Java 单元测试中的HashSet
我有很多方法返回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对象:行){ //如何确认内容?
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"), ...));