2

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?

Jethro
  • 3,029
  • 3
  • 27
  • 56
  • 1
    Without having worked with scala-mockito, my educated guess would be no. Overloaded methods are just methods with the same name, they're still different methods (different signatures). There is no way you can mock all overloaded methods without heavy use of reflection. – Markus Appel Oct 21 '19 at 14:58

1 Answers1

2

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")
  }
}
Mario Galic
  • 47,285
  • 6
  • 56
  • 98
  • @Jethro Please see edited answer because there was a bug in the original implementation where I was missing `ReturnsDefaults.answer(invocation)` – Mario Galic Oct 21 '19 at 18:24