Search code examples
scalascalamock

How to call real method on a stub


Is there a way to call a real method on a stubbed object with scalamock?

I would like to be able to do something like this:

class MySpec extends FunSpec with Matchers with MockFactory {
  trait MyTrait {
    def f1: Int
    def f2: Int = f1
  }

  describe("my feature") {
    it("should work") {
      val t = stub[MyTrait]
      (t.f1 _).when().returns(15)
      // I would like to do the following:
      // (t.f2 _).when().callRealMethod()
      t.f2 should be (15)
    }
  }
}

Note: I was able to work around the issue by making f2 final but I would like to know if there is a way to do it without changing the code under test.


Solution

  • The pattern that I could recommend is to make the function you don't want to mock final, as you suggested. But rather than doing this in the real code, you use a subclass that's only used for test purposes, e.g. like this:

    import org.scalamock.scalatest.MockFactory
    import org.scalatest.FunSuite
    import PartialMockingTest._
    
    class PartialMockingTest extends FunSuite with MockFactory {
    
      test("test case") {
    
        class PartFinalCls extends Cls {
          override final def B(): Int = super.B()
        }
    
        val f = stub[PartFinalCls]
        f.A _ when 7 returns 5
        assert(f.B() == 6)
      }
    
    }
    
    object PartialMockingTest {
      class Cls {
        def A(dummy: Int): Int = 5
    
        def B(): Int = A(7) + 1
      }
    }