Search code examples
scalaplayframeworkmockitospecs2

Mocking default values for return types with mockito + specs2


Given a mock:

val myMock = mock[SomeClass]

I am trying to set it up so that the mock returns default values for various types. E.g. for things that returns String, it would return "".

I discovered RETURNS_SMART_NULLS which looks like it works for basic return types like String. Here is how I am using it in Scala / Specs2:

val myMock = mock[SomeClass].settings(smart = true)

Now to the problem: since I am using Scala, my code / APIs do not return nulls but return Option values. So what I am trying to do is get the mock to default to returning a non null value for Option return types: either None (preferred), or Some[T] where T is the type in the container (if its String, then Some("")).

So for example if SomeClass has an attribute address of type Option[String], how can I configure mockito to return None when myMock.address invoked instead of null. These nulls are causing downstream errors.

Note, its not a viable solution for me to specifically mock the behavior of each of these individual invocations (e.g: myMock.address returns None)


Solution

  • I was able to test this class:

    class Timers(i: Int, s: String) {
      def returnOption: Option[Int] = Some(i)
      def returnString: String = s
    }
    

    with this test:

    import org.specs2.mutable.Specification
    import org.junit.runner.RunWith
    import org.specs2.runner.JUnitRunner
    import org.mockito.Mockito._
    import org.mockito.stubbing.Answer
    import org.mockito.invocation.InvocationOnMock
    
    @RunWith(classOf[JUnitRunner])
    class TimersSpec extends Specification {
    
      val m = mock(classOf[Timers], new Answer[Any]() {
            def answer(inv: InvocationOnMock) = {
              inv.getMethod.getReturnType match {
                case c if c == classOf[Option[_]] => None
                case c if c == classOf[String] => ""
                case _ => null
              }
            }
          })
    
      "A mock timer" should {
        "return a None" in {     
          m.returnOption must beNone
        }
        "return a empty string" in {
          m.returnString mustEqual ""
        }
      }
    }