Search code examples
scalamockitoscalatestvalue-classmockito-scala

Mocked function doesn't return value class correctly in Scala


I need to mock a function from an arbitrary type to another type that is a . For example with the following signature String => ValueClass. This is how my is implemented:

final case class ValueClass(value: String) extends AnyVal

I am using to mock and to matche result:

import org.mockito.{ArgumentMatchersSugar, MockitoSugar}
import org.scalatest.{Matchers, WordSpecLike}

class ValueClassMockTest 
   extends WordSpecLike
    with MockitoSugar
    with ArgumentMatchersSugar
    with Matchers {

  "mocked function" should {
    "return the same value class" in {
      val f: String => ValueClass = mock[String => ValueClass]

      when(f(any[String])).thenReturn(ValueClass("str"))

      f("anyStringValue") shouldEqual ValueClass("str")
    }
  }

}

I wondering, why this test doesn't pass and mocked function returns unwrapped value?

"str" did not equal ValueClass(str)
ScalaTestFailureLocation: services.ValueClassMockTest at (ValueClassMockTest.scala:16)
Expected :ValueClass(str)
Actual   :"str"
<Click to see difference>

build.sbt

scalaVersion       = "2.12.10"
scalaTest          = "3.0.8"
mockitoScala       = "1.5.17"

Solution

  • Fixed in v1.5.18 (https://github.com/mockito/mockito-scala/pull/152)

    The issue comes from the fact that on a parametrised return type there is no type info in runtime, hence the value class is always boxed, I added extra provisions for those scenarios so the boxed instance is returned.

    That said, for stuff like functions I think is a better idea to skip mocking altogether, unless the function is impure or you want to assert some unorthodox behaviour.