Mockito: 0 matchers expected, 1 recorded

713 Views Asked by At

I have the folliwng PlaySpec:

"Service A" must {

   "do the following" in {
       val mockServiceA = mock[ServiceA]
       val mockServiceB = mock[ServiceB]
       when(mockServiceA.applyRewrite(any[ClassA])).thenReturn(resultA) // case A
       when(mockServiceB.execute(any[ClassA])).thenReturn(Future{resultB})

       // test code continuation
   }
} 

The definition of ServiveA and ServiceB are

class ServiceA {
    def applyRewrite(instance: ClassA):ClassA = ???
}

class ServiceB {
   def execute(instance: ClassA, limit: Option[Int] = Some(3)) = ???
}

Mocking ServiceA#applyRewrite works perfectly. Mocking ServiceB#execute fails with the following exception:

Invalid use of argument matchers!
0 matchers expected, 1 recorded:
-> at RandomServiceSpec.$anonfun$new$12(RandomServiceSpec.scala:146)

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));

Although the instructions included in the exception seem a bit counterintuitive to me I have tried the following:

when(mockServiceB.execute(anyObject[ClassA])).thenReturn(Future{resultB})
when(mockServiceB.execute(anyObject())).thenReturn(Future{resultB})
when(mockServiceB.execute(anyObject)).thenReturn(Future{resultB})
when(mockServiceB.execute(any)).thenReturn(Future{resultB})
when(mockServiceB.execute(any, Some(3))).thenReturn(Future{resultB})
when(mockServiceB.execute(any[ClassA], Some(3))).thenReturn(Future{resultB})

All unfortunately to no avail. The only thing that changes is the number of expected and recorded matchers the exception refers to.

The weirdest thing for me though is that the mocking works perfectly for case A.

2

There are 2 best solutions below

2
On BEST ANSWER

Use the idiomatic syntax of mockito-scala and all the stuff related to the default argument will be deal with by the framework

mockServiceB.execute(*) returns Future.sucessful(resultB)

if you add the cats integration it could reduce to just

mockServiceB.execute(*) returnsF resultB

more info here

3
On

You need to do this:

import org.mockito.ArgumentMatchersSugar._

when(mockServiceB.execute(any[ClassA], eqTo(Some(3)))).thenReturn(Future{resultB})

When you use any and the function receives multiple arguments you need to pass the other arguments that are not any with eq(something), hope this helps.

EDITED: My bad forgot the import and is eqTo and not eq