12

I'd like to stub one of the methods of a scala class with dependencies. Is there a way to achieve this using ScalaMock?

Here is a simplified example of what I have:

class TeamService(val dep1: D1) {

  def method1(param: Int) = param * dep1.magicNumber()

  def method2(param: Int) = {
    method1(param) * 2
  }
}

In this example I'd like to mock method1(). My test would look like:

val teamService = ??? // creates a stub
(teamService.method1 _).when(33).returns(22)
teamService.method2(33).should be(44)

Is there a way to achieve this?

Danix
  • 1,947
  • 1
  • 13
  • 18
  • I think that if you are mocking some class, you don't want to depend on its implementation, but now you seem to be trying to depend on implementation of `method1` and on `D1`. Maybe there is not enough information but you maybe should mock all methods you need to use. – Łukasz Jan 26 '16 at 15:56
  • looks like scala mock doesn't support this feature :( – Danix May 18 '16 at 16:07
  • 1
    I belive there is an issue asking for this feature here : https://github.com/paulbutcher/ScalaMock/issues/141 – Quentin Nov 07 '16 at 12:59

3 Answers3

1

As suggested in other questions, here and here, we can combine stub with final. From ScalaMock FAQ:

Can I mock final / private methods or classes?

This is not supported, as mocks generated with macros are implemented as subclasses of the type to mock. So private and final methods cannot be overridden

So you can either declare method2 in your source code as final, and then test:

it should "test" in {
  val teamService = stub[TeamService]
  (teamService.method1 _).when(33).returns(22)
  teamService.method2(33) shouldBe 44
}

Or, create a new overriding class that declares your method as final:

it should "test" in {
  class PartFinalTeamService(dep: D1) extends TeamService(dep) {
    override final def method2(param: Int): Int = super.method2(param)
  }

  val teamService = stub[PartFinalTeamService]
  (teamService.method1 _).when(33).returns(22)
  teamService.method2(33) shouldBe 44
}
Tomer Shetah
  • 8,413
  • 7
  • 27
  • 35
0

You must mock dep1: D1, so everything gonna works well. It's not a good approach to mock "half" or only some methods.

Mocking dep1: D1 is the right way to test it.

val mockD1 = mock[D1]
val teamService = new TeamService(mockD1)
(mockD1.magicNumber _).returns(22)
teamService.method2(33).should be(44)
Henrique Goulart
  • 1,815
  • 2
  • 22
  • 32
0

You can override method1() while creating the TeamService object and make it return whatever value you want.

val service = new TeamService(2) {
  override def method1(param: Int): Int = theValueYouWant
}

And use the service object to test your method2().

jwvh
  • 50,871
  • 7
  • 38
  • 64
Manoj Kumar
  • 68
  • 1
  • 7