Say I have something like this (VERY OVER-SIMPLIFIED):
case class Foo(bar: String)
val mockFnThatTakesFoo = mock[Foo => Unit]
def fooHasBarSetTo(expectedBar: String, foo: Foo): Boolean = {
val actualBar = foo.bar
actualBar shouldEqual expectedBar
true
}
mockFnThatTakesFoo(argThat(fooHasBarSetTo("blah", _))) wasCalled once
This works. However, the assertion itself is a little bit convoluted and it could be made more readable.
I tried this:
val withFooHavingBarSetTo = (expectedBar: String) => argThat(fooHasBarSetTo(expectedBar, _))
//and then
mockFnThatTakesFoo(withFooHavingBarSetTo("blah")) wasCalled once
Much neater! but doesn't work :/
> [info] FooSpec:
[info] - should do stuff *** FAILED ***
[info] org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Invalid use of argument matchers!
[info] 1 matchers expected, 2 recorded:
[info] -> at com.foo.FooSpec.argThat(FooSpec.scala:28)
[info] -> at com.foo.FooSpec.$anonfun$new$5(FooSpec.scala:204)
Any idea how can this be done?
I believe Mockito is implemented using macro and it tracks positions where
argThat
and other Mockito methods are placed. For example if you try to create a variable likeYou will get an exception "Misplaced or misused argument matcher detected here". So it is impossible to return argThat matcher from another method.
If you need to reuse mock matcher with different argument value I see only one possible solution like