Mockito可以根据方法调用时的值validation参数吗?

我有一个Foo类,它是SUT和一个Bar类,它是它的合作者。 Foo使用“ expectedList ”作为参数调用Bar上的run(List values) 。 然后, Foo将向此List添加一些元素,以使其状态与调用run()时的状态不同。 这是我的测试用例。

 @Test public void testFoo() { Bar collaborator = spy(new Bar()); Foo sut = new Foo(collaborator); verify(collaborator).run(expectedList); } 

请注意,协作者实际上是间谍对象而不是模拟对象。 此测试用例将失败,因为即使使用等于expectedList的参数调用run() ,它也会被修改,因为它的当前值不再等于expectedList 。 然而,这是它应该工作的方式,所以我想知道是否有办法让Mockito在调用方法时存储参数的快照,并根据这些值而不是最近的值来validation它们。

调用方法时,使用Answer检查参数的值。 如果值错误,您可以在Answer抛出AssertionError ,或者您可以存储该值,并在最后执行您的断言。

Dawood ibn Kareem的答案为我工作,但我缺少一个例子,我也使用Kotlin和Mockito-Kotlin ,所以我的解决方案是这样的:

 class Foo(var mutable: String) interface Bar { fun run(foo: Foo) } @Test fun `validate mutable parameter at invocation`() { val bar = mock() var valueAtInvocation: String? = null whenever(bar.run(any())).then { val foo = it.arguments.first() as Foo valueAtInvocation = foo.mutable // Store mutable value as it was at the invocation Unit // The answer } val foo = Foo(mutable = "first") bar.run(foo) valueAtInvocation isEqualTo "first" foo.mutable = "second" bar.run(foo) valueAtInvocation isEqualTo "second" } 

valueAtInvocation将表示最后一次调用bar.run(foo)可变属性foo.mutable的值。 也应该可以在then {}块中进行断言。

您不能在非mock对象上调用verify() 。 这是你的意思吗?

 Bar collaborator = mock(Bar.class); Foo sut = spy(new Foo(collaborator)); verify(collaborator).run(expectedList); 

为什么不尝试使用参数捕获来获取运行时预期列表的值,然后您可以比较它。

 ArgumentCaptor listCaptor = ArgumentCaptor.forClass(List.class); verify(collaborator).run(listCaptor.capture()); assertEquals(expectedList, argument.getValue());