我想测试我的类'equals()方法,但Mockito似乎每次调用存根版本。我的测试如下;
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应该调用我的真实实现但不是。
我也试过这个:
when (adapter.equals(any()).thenCallRealMethod()
但我得到的结果相同。
答案 0 :(得分:13)
即使超出Mockito's limitations,对于模拟对象使用真正的equals
方法也没有多大意义,如果没有其他原因,等于方法几乎总是使用字段和模拟对象永远不要运行任何构造函数或字段初始化器。
另外,请注意您正在测试的内容:在Foo
的测试中,理想情况下,您不应该模拟Foo
,甚至要设置Foo
进行比较。否则,很容易无意中测试Mockito的工作原理,而不是测试你自己组件的逻辑。
您有一些解决方法:
正如Garrett Hall所提到的,创造真实的物体。这可能需要从使用它们的服务中分解出“数据对象”,并在使用真实数据对象时模拟服务。这可能是一个好主意。
通过继承PluginResourceAdapter或在Mockito之外实现相关接口来创建手动模拟或伪造。这使您可以根据需要定义所有方法,包括equals
和hashCode
。
创建一个equivalentTo
方法,它与equals
不同(例如,对于Map或Set对象不那么有用)但是你有可模糊的语义可以自己定义。
这也可以让你通过模拟自由地测试equivalentTo
,并且只需要equals
委托给那个可能经过良好测试的实现。
提取测试相等性的对象,并模拟它。您也可以使用Guava's Equivalence
或Comparator
来测试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();
}
请注意,另一个可能的解决方法 - spying on existing instances - 也会redefine equals
and hashCode
,并且不会对您有所帮助。
答案 1 :(得分:2)
如果您想测试真实 equals
,那么您需要创建一个真实的对象并在其上调用equals
方法。我不确定你为什么要使用嘲笑。
答案 2 :(得分:2)
默认情况下,如果对象在内存中具有相同的地址,则equals()将返回true
所以
PluginResourceAdapter adapter;
PluginResourceAdapter other;
adapter = other = mock (PluginResourceAdapter.class);
返回true给你。如果您想要错误使用
PluginResourceAdapter adapter = mock (PluginResourceAdapter.class);
PluginResourceAdapter other = mock (PluginResourceAdapter.class);