Search code examples
scalatestingplayframeworkscalamock

Mocking in scala generates a java.lang.NoSuchMethodException


Hey I am trying to test the following class :

class Foo {
 def f: Int = 4 + g

 def g: Int = 2
}

My test is the following:

class FooSpec extends PlaySpec with MockFactory {
  val foo = new Foo()
  "Foo" must {
    "Call function f" in {
        (foo.g _)
        .expects()
        .once()
        .returns(5)

        foo.f must be (9)
     }
   }
}

My test is failing saying that :

java.lang.NoSuchMethodException: Foo.mock$g$0()
java.lang.Class.getMethod(Unknown Source)
...

I am not sure to see why ...

I am using scalatest and scalamock :

"org.scalatestplus.play" %% "scalatestplus-play" % "1.5.0" % "test"
"org.scalamock" %% "scalamock-scalatest-support" % "3.2.2" % "test"

Solution

  • I see two problems here:

    1. You cannot establish mocked answers without actually mocking an object: you create val foo = new Foo(), but you have to mock this class first: val foo = mock[Foo]
    2. It looks like ScalaMock doesn't support partially stubbing instances, so you cannot stub method g and expect it to get called when you invoke f - you'll have to restructurize your code in a way that Foo.g is called from another class - wrap it in a delegate perhaps. Or use Mockito - it's not as fancy and does its magic in runtime as opposed to ScalaMock's compile time, but it provides an ability to callRealMethod() on a mocked class.

    Basically ScalaMock works best when you mock or stub traits, not classes - their macros don't have to process actual implementations of the methods, and noone would expect them to.