Search code examples
scalamockito-scala

Mocking out all overlaoded versions of a method in scala mockito


In Mockito-Scala you can stub out methods like so:

myMock.doIt(*) returns 1
myMock.doIt(*,*) returns 1
myMock.doIt(*,*)(*) returns 1

Is there a way to mock all overloaded methods at once?


Solution

  • ScalaAnswer[T] can be used to configure mock's answers like so

    object AnswerAllFoo extends ScalaAnswer[Any] {
      def answer(invocation: InvocationOnMock): Any = {
        if (invocation.getMethod.getName == "foo") 42 else ReturnsDefaults.answer(invocation)
      }
    }
    

    and then pass it in on mock creation like so

    mock[Qux](AnswerAllFoo)
    

    Here is a complete working example

    import org.mockito.invocation.InvocationOnMock
    import org.mockito.stubbing.{ReturnsDefaults, ScalaAnswer}
    import org.scalatest.{FlatSpec, Matchers}
    import org.mockito.{ArgumentMatchersSugar, IdiomaticMockito}
    
    trait Qux {
      def foo(s: Seq[Int]): Int
      def foo(i: Int, j: String): Int
      def bar(s: String): String
    }
    
    object AnswerAllFoo extends ScalaAnswer[Any] {
      def answer(invocation: InvocationOnMock): Any = {
        if (invocation.getMethod.getName == "foo") 42 else ReturnsDefaults.answer(invocation)
      }
    }
    
    class MockAnyOverload extends FlatSpec with Matchers with IdiomaticMockito with ArgumentMatchersSugar {
      "Answer[T]" should "should answer all overloaded methods foo" in {
        val qux = mock[Qux](AnswerAllFoo)
    
        qux.foo((Seq(1,0))) shouldBe (42)
        qux.foo(1, "zar") shouldBe (42)
    
        qux.bar(*) returns "corge"
        qux.bar("") shouldBe ("corge")
      }
    }