防止equals方法的存根 [英] Prevent stubbing of equals method

查看:19
本文介绍了防止equals方法的存根的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想测试我的班级的 equals() 方法,但 Mockito 似乎每次都在调用存根版本.我的测试如下;

I would like to test my class' equals() method but Mockito seems to be calling the stub version every time. My test is as follows;

PluginResourceAdapter adapter = mock (PluginResourceAdapter.class);
PluginResourceAdapter other = mock (PluginResourceAdapter.class);

when(adapter.getNumberOfEndpointActivation()).thenReturn(1);
when(other.getNumberOfEndpointActivation()).thenReturn(0);

boolean result = adapter.equals(other);
assertFalse(result);

我知道我不能存根 equals 方法,这意味着 Mockito 应该调用我的真正实现,但它不是.

I know I cannot stub the equals method which means Mockito should be calling my real implementation but its not.

我也试过这个:

when (adapter.equals(any()).thenCallRealMethod()

但我得到了相同的结果.

but I get the same result.

推荐答案

甚至超越 Mockito 的局限性,模拟对象使用真正的 equals 方法没有多大意义,如果没有其他原因,几乎等于方法总是使用字段,并且模拟对象从不运行它们的任何构造函数或字段初始值设定项.

Even beyond Mockito's limitations, it doesn't make much sense for a mocked object to use a real equals method, if for no other reason than that equals methods almost always use fields, and mocked objects never run any of their constructors or field initializers.

另外,请注意您正在测试的内容:在 Foo 的测试中,理想情况下,您永远不应该模拟 Foo,即使设置 Foo 进行比较.否则,很容易在不经意间测试 Mockito 是否有效,而不是测试您自己组件的逻辑.

Also, be aware of what you're testing: In a test of Foo, ideally you should never mock Foo, even to set up a Foo to compare against. Otherwise, it's easy to inadvertently test that Mockito works, rather than testing your own component's logic.

您有一些解决方法:

  • 正如 Garrett Hall 所说,创建真实的对象.这可能需要从使用它们的服务中提取数据对象",并在使用真实数据对象时模拟服务.总体而言,这可能是一个好主意.

  • As Garrett Hall mentioned, create real objects. This may require factoring out the "data objects" from the services that use them, and mocking the services while using real data objects. This is probably a good idea overall.

通过子类化 PluginResourceAdapter 或在 Mockito 之外实现相关接口来创建手动模拟或伪造.这使您可以根据需要定义所有方法,包括 equalshashCode.

Create a manual mock or fake by subclassing PluginResourceAdapter or implementing the relevant interface outside of Mockito. This frees you to define all methods as needed, including equals and hashCode.

创建一个 equivalentTo 方法,它与 equals 不同(因此对 Map 或 Set 对象没有那么有用)但它具有可模拟的语义,您可以自行定义.

Create an equivalentTo method, which isn't the same as equals (and thus isn't as useful for Map or Set objects, for instance) but that has mockable semantics you can define on your own.

这还可以让您使用模拟自由地测试 equivalentTo,并且只需将 equals 委托给那个可能经过良好测试的实现.

This would also let you test equivalentTo freely with a mock, and simply have equals delegate to that presumably-well-tested implementation.

提取一个测试相等性的对象,然后模拟它.您还可以使用 Guava 的 Equivalence 那里,或者你测试 a.compareTo(b) == 0Comparator.

Extract an object that tests equality, and mock that. You could also use Guava's Equivalence there, or a Comparator where you test a.compareTo(b) == 0.

class YourClass {
  class AdapterEquivalence {
    boolean adaptersAreEqual(
        PluginResourceAdapter a, PluginResourceAdapter b) {
      return a.equals(b);
    }
  }

  /** Visible for testing. Replace in tests. */
  AdapterEquivalence adapterEquivalence = new AdapterEquivalence();
}

请注意,另一种可能的解决方法 - 监视现有实例——还将重新定义equalshashCode 在这里帮不了你.

Note that one other potential workaround—spying on existing instances—will also redefine equals and hashCode and won't help you here.

这篇关于防止equals方法的存根的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆