我无法判断这是否支持功能。我想模拟一个对象被提供给模拟方法时的行为。 Examples for "when"给出了文档中的整数或字符串,但可以为对象完成。是否需要为每个所需的返回对象定义custom matcher类?
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方法以将等式计算为p1.equals(p2)。
答案 0 :(得分:1)
您可以将具体参数以及参数匹配器与任何对象一起使用。所以这应该可以正常工作。
when(mockPoint.goEast(p1)).thenReturn(p3)
当p3
用作参数时,它将模拟配置为返回p1
。要将它与参数匹配器结合使用(因为具体的参数和匹配器可能不会混合),我通常使用默认的eq
匹配器。
// assuming a second goEast method with an int parameter
when(mockPoint.goEast(eq(p1), anyInt())).thenReturn(p3)
答案 1 :(得分:1)
是的,您可以像返回原始值一样返回对象实例。
只要覆盖有问题的对象(Point)上的equals
和hashCode
,就不需要自定义匹配器。默认情况下,或使用eq
匹配器,Mockito将使用对象的equals
方法来确定对象是否相等 - 如果没有覆盖,则只有相等的引用(==
)将被视为相等。如果任何一个点(2,3)等于任何其他点(2,3),这是表达它的正确的地点和时间。
Point是覆盖equals
和hashCode
的特别好的候选者,因为点等式定义明确且易于计算,并且不依赖于外部服务或数据。对于比Point更棘手的对象,参数匹配器是一个很好的解决方案。
正如tieTYT所提到的,在断言中调用存根方法很少见。对于任何给定的测试,确保您知道正在测试哪个单一系统或对象,使用 该对象的mocks为其提供可预测的环境,然后测试您是否获得了预期值或预期的调用嘲笑。在断言中调用模拟通常会导致混乱,脆弱或重言式测试。
在这里,如果你正在测试Point,你可能不需要模拟 - 尤其不是模拟点。如果您正在测试Maze,您仍然不需要模拟点,因为您可以使用真实的测试点。但是,测试游戏可能需要一个模拟迷宫,所以如果迷宫是复杂的或随机的,你的测试可能更简单和确定。