JUnit assertEquals 因 HashSet 而失败

JUnit assertEquals failing with HashSet

我正在为 AddressBook 做一些 JUnit 测试 并一直未能实施我的一项测试。这是那个测试:

@Test
public void parseIndices_collectionWithValidIndices_returnsIndexSet() throws Exception {
    Set<Index> actualIndexSet = ParserUtil.parseIndices(Arrays.asList(VALID_INDEX_1, VALID_INDEX_2));

    Index index = Index.fromOneBased(Integer.valueOf(VALID_INDEX_1));
    Index index2 = Index.fromOneBased(Integer.valueOf(VALID_INDEX_2));
    Set<Index> expectedIndexSet = new HashSet<>();
    expectedIndexSet.add(index);
    expectedIndexSet.add(index2);

    assertEquals(expectedIndexSet, actualIndexSet);
}

输出结果如下:

它表明它们是相等的,但是断言总是以某种方式失败。然后我尝试断言 2 个 actualIndexSets(如下所示)以查看它们是否会通过测试,但它仍然失败,结果相同,这很奇怪。

@Test
public void parseIndices_collectionWithValidIndices_returnsIndexSet() throws Exception {
    Set<Index> actualIndexSet = ParserUtil.parseIndices(Arrays.asList(VALID_INDEX_1, VALID_INDEX_2));
    Set<Index> actualIndexSet2 = ParserUtil.parseIndices(Arrays.asList(VALID_INDEX_1, VALID_INDEX_2));

    Index index = Index.fromOneBased(Integer.valueOf(VALID_INDEX_1));
    Index index2 = Index.fromOneBased(Integer.valueOf(VALID_INDEX_2));
    Set<Index> expectedIndexSet = new HashSet<>();
    expectedIndexSet.add(index);
    expectedIndexSet.add(index2);

    assertEquals(actualIndexSet2, actualIndexSet);
}

这里的问题显然是不对的,因为当我断言 2 组 actualIndexSet 时它失败了,因为断言索引 class 工作正常。

HashSet 重写 equals;它检查第一组是否包含第二组的所有内容。

唯一可能的原因是您的索引 class 没有覆盖等于。 当调用 containsAll 方法时,它将遍历所有索引元素并检查 equals 的结果是否为真。

您的问题似乎是 equals 方法及其在 Index class.

中的定义方式

我建议使用像 apache commons 这样的库来为你解决这个问题:

CollectionUtils.isEqualCollection(expectedIndexSet, actualIndexSet)
@Override
public int hashCode() {
    return zeroBasedIndex;
}

覆盖索引中的 hashCode 方法 class 解决了它。