Reputation: 9540
I have the following class:
class Elem[T](t: T){
def doSome(f: T => Unit):Unit = f(t)
}
So I want to test function invokation for the given Elem
instance (I'm doing with mockito). When running the test
val f = mock(classOf[Int => Unit])
new Elem(1).doSome(f)
verify(f).apply(1)
I got the following exception:
Wanted but not invoked:
function1.apply$mcVI$sp(1);
However, there was exactly 1 interaction with this mock:
function1.apply(1);
That's reasonable because Function1
is specialized for Int
. So making the test as
val f = mock(classOf[AnyRef => Unit])
new Elem(1.asInstanceOf[AnyRef]).doSome(f)
verify(f).apply(1.asInstanceOf[AnyRef])
works fine.
Is there a way to avoid this ugly casts to AnyRef
? Maybe there is another tool more suitable for this case than mockito?
Upvotes: 2
Views: 46
Reputation: 48420
ScalaMock seems to work out-of-the-box:
import org.scalatest._
import org.scalatest.matchers._
import org.scalamock.scalatest.MockFactory
import org.scalamock.scalatest._
class Elem[T](t: T){
def doSome(f: T => Unit):Unit = f(t)
}
class ExampleSpec extends FlatSpec with Matchers with MockFactory {
"Elem.doSome" should "apply given function once" in {
val f = mockFunction[Int, Unit]
f.expects(1).returning({}).once
new Elem(1).doSome(f)
}
}
run(new ExampleSpec)
Upvotes: 2
Reputation: 44928
Here is one way to force the compiler to use the non-specialized generic apply
:
def verifyGenericApply[X, Y](f: X => Y, x: X): Unit = {
verify(f).apply(x)
}
"Int function" should "invoke non-specialized apply" in {
class Elem[T](t: T){
def doSome(f: T => Unit):Unit = f(t)
}
val f = mock(classOf[Int => Unit])
new Elem(1).doSome(f)
verifyGenericApply(f, 1)
}
I'm not familiar enough with mockito
to guarantee that this is idiomatic, though...
Upvotes: 4