我不知道这是否是支持的功能。当一个对象被提供给一个模拟方法时,我想模拟它的行为。文档中给出了整数或字符串的"when"示例,但对象也可以这样做。是否需要为每个所需的返回对象定义一个自定义匹配器类?
Class Point
Point (int X, int Y)
Class ItemMover
goEast(Point p) {
return new Point(p.getX() + 1, p.getY())
Class App
ItemMover itemMover
Point currentPosition
main() {
def p1 = new Point(1,1)
currentPosition = itemMover.goEast(p1)
Class AppTest
def itemMover = Mock(ItemMover)
def p1 = new Point(1,1)
def p2 = new Point(2,1)
when(itemMover.goEast(p1)).thenReturn(p2)
app.main()
assertEquals(app.currentPosition.getX(), 2)
更新:基于以下答案。当X和Y相等时,需要实现对象的equals和hashCode方法来将equality计算为p1。equals(p2)。
-
是的,您可以像返回基元值一样返回对象实例。
-
只要覆盖有问题对象(Point)上的
equals
和hashCode
,就不需要自定义Matcher。默认情况下或使用eq
匹配器时,Mockito将使用对象的equals
方法来确定对象是否相等——如果没有覆盖,则只有相等引用(==
)将被视为相等。如果任何一点(2,3)等于任何其他点(2、3),这是表达这一点的正确地点和时间。点是覆盖
equals
和hashCode
的一个特别好的候选者,因为点等式定义明确且易于计算,并且不依赖于外部服务或数据。对于比Points更棘手的对象,参数匹配器是一个很好的解决方案。 -
正如tieTYT所提到的,很少在断言中调用存根方法。对于任何给定的测试,请确保您知道要测试的是哪一个系统或对象,在对象周围使用mock为其提供一个可预测的环境,然后测试您是否在mock上获得预期值或预期调用。在断言中调用mock通常会导致混淆、脆弱或重复的测试。
在这里,如果您正在测试Point,您可能不需要mock——尤其是不需要mockPoint。如果你在测试迷宫,你仍然不需要模拟点,因为你可以使用真实的测试点。然而,测试游戏可能需要一个模拟迷宫,所以如果迷宫是复杂的或随机的,你的测试可能会更简单和确定。
您可以对任何对象使用具体的参数以及参数匹配器。所以这应该很好用。
when(mockPoint.goEast(p1)).thenReturn(p3)
当p1
用作参数时,它将mock配置为返回p3
。为了将其与参数匹配器相结合(因为具体的参数和匹配器可能不会混合),我通常使用默认的eq
匹配器。
// assuming a second goEast method with an int parameter
when(mockPoint.goEast(eq(p1), anyInt())).thenReturn(p3)