【问题标题】:Ambiguous equality of collections when verifying arguments with mockito使用 mockito 验证参数时集合的模棱两可的相等性
【发布时间】:2013-01-07 07:41:31
【问题描述】:

mockito 验证方法是匹配集合的相同实例还是验证集合的元素? 如果我在 Page#equals() 方法上设置一个断点,它不会被触发。只有 Page#hashCode() 可以。知道为什么 Mockito 在具有相同元素时不认为 Set 的 2 个实现是相等的吗?

Set<Page> pagesToRemove = Sets.newHashSet();
// add a few pages
Set<Page> copy = ImmutableSet.copyOf(pagesToRemove)
pageManager.removePages(copy);
verify(pageManager, new Times(1)).removePages(pagesToRemove);

Page 上的 Equals 和 HashCodes 方法具有从 Object 继承的默认实现。

参数不同!通缉:pageManager.removePages( (HashSet) [{ pageId : null;父母身份:空;第一个孩子:空; nextSibling : null } 等...] ); -> 在 com.fg.edee.integration.service.PageServiceTest.testRemove(PageServiceTest.java:60) 实际调用有不同的参数: pageManager.removePages( (RegularImmutableSet) [{ pageId : null;父母身份:空;第一个孩子:空; nextSibling : null }, etc..] );

【问题讨论】:

  • 我相信 Mockito 只是使用 equals 来检查是否相等。你可以尝试做类似assertEquals(pagesToRemove, copy) 的事情来看看它是否有效?

标签: java mocking mockito


【解决方案1】:

在验证使用引用类型对象作为参数调用的方法时,您可以使用 ArgumentMatcher。见here。

【讨论】:

    【解决方案2】:

    我写了一些测试,发现它只是一个 HashSet hashCode 的东西。正如我所说,我使用的是原生 Object#hashCode 和:

    一个关键的限制是在标准的 Java 实现中,哈希 代码不能唯一标识一个对象。他们只是缩小了范围 选择匹配项,但预计在正常使用中,有 很有可能多个对象共享相同的哈希码。

    这很容易引起误解,因为原生 Object#hachCode() 方法在执行过程中总是返回相同的整数。

    【讨论】:

    • 这里的关键问题可能是您已经为Page 对象实现(覆盖)了equals 方法,但没有实现hashCode 方法。这不好,因为所有集合实现都依赖于哈希码中断。如果您的equals 方法认为两个Page 对象相等,则它们必须共享相同的哈希码。请参阅 Bloch 的“Effective Java”中的第 9 条(“如果您覆盖 equals,总是 覆盖 hashCode),我强烈建议您阅读。
    • 但是 HashSet#contains 方法计算输入参数的 hashCode 并尝试在集合中是否有一个元素,正在测试相等性,它具有此 hashCode。考虑到这样一个事实,即 X Object#hashCode 对同一个 Object 实例的调用并不总是返回相同的 hashCode,那么具有 X 个相同实例的 Set 不可能很可能相等。 equal 方法在这个用例中是完全不相关的
    • 我遇到这种情况是因为这些实体已被销毁,并且没有用于计算 hashCode 的业务密钥,所以我调用了 Object#hashCode...我通过保留原始的 'beforeDestroyHashcode' 解决了这个问题在我摧毁实体之前
    • 没错,hashSet/equals 实现在这里不起作用,因为 google 的 ImmutableSet.copyOf 将对原始对象的引用放入新集合中,集合中的对象不会被复制. 但是您说:X Object#hashCode 对同一个 Object 实例的调用并不总是返回相同的 hashCode,这肯定是错误的,或者至少会破坏general contract 用于 hashCode 方法!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 2015-03-08
    相关资源
    最近更新 更多