2

I have a method with this signature:

def foo(param1: => String, param2: (String, String)*)(implicit param3: Context): Unit

In my code, I call it as

foo("bar") // no varargs, implicit is in scope

In my Unit test, I am trying to verify the call:

  verify(mock).foo(stringCaptor.capture())(any[Context])

This compiles, but produces a runtime exception:

Invalid use of argument matchers! 3 matchers expected, 1 recorded: -> at com.mycompany.MySpec$$anon$3.(MySpec.scala:88) 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")); For more info see javadoc for Matchers class. org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Invalid use of argument matchers! 3 matchers expected, 1 recorded:

Yet if I try to match the varargs parameter, I get compilation errors:

  verify(mock).foo(stringCaptor.capture(), any[Seq[(String, String)]])(any[Context])

Cannot resolve overloaded method 'foo'

What would be the syntax to match my method and verify the call correctly?

Note: answers to other questions suggest adding a dependency to mockito-scala, which I'd like to avoid

Update: adding a matcher for a tuple reduces the missing matchers from 1 to 2:

  verify(mock).foo(stringCaptor.capture(),any[(String, String)])(any[Context])

Invalid use of argument matchers! 3 matchers expected, 2 recorded: [...]

(it doesn't make a difference if I replace the ArgumentCaptor with anyString())

Another Update:

Ah, it seems the => String part causes the problem, didn't realize that I'm trying to match a lazy string here. Under the hoods, the compiler seems to turn my String into a Function0[String], but how can I match that?

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • 1
    Have you tried `any[(String, String)]`? – amorfis Sep 12 '21 at 20:41
  • @amorfis that improves things, but doesn't fix them (see update) – Sean Patrick Floyd Sep 12 '21 at 21:05
  • I am not as much of Mockito person, since I use ScalaMock in Scala. But it seems after your investigative work, you found that the by-name parameter is converted to a `Function0` so you can try `val f:Function0[String] = () => "What you're trying to match"` as what you are trying to match. Let us know. ;) – Daniel Hinojosa Sep 13 '21 at 03:11
  • And then using the above, perhaps you can do the following. It seems you will need to ensure that you are using the same function reference. Again, let us know if that makes sense and if that helps. https://stackoverflow.com/a/41463510/631666 – Daniel Hinojosa Sep 13 '21 at 03:18
  • Looks to me like you need to capture not a `String`, but a `Function0[String]`. Create captor for such function, in captor call the function and you'll have the string passed in test. Then you can check if it was expected value or not. – amorfis Sep 13 '21 at 07:34

0 Answers0