防止equals方法的存根 [英] Prevent stubbing of equals method
问题描述
我想测试我的班级的 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 之外实现相关接口来创建手动模拟或伪造.这使您可以根据需要定义所有方法,包括 equals
和 hashCode
.
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) == 0
的 Comparator
.
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();
}
请注意,另一种可能的解决方法 - 监视现有实例——还将重新定义equals
和hashCode
在这里帮不了你.
Note that one other potential workaround—spying on existing instances—will also redefine equals
and hashCode
and won't help you here.
这篇关于防止equals方法的存根的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!