Danix
Danix

Reputation: 1947

Scala Mock partial stubbing

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?

Upvotes: 12

Views: 2722

Answers (3)

Manoj Kumar
Manoj Kumar

Reputation: 68

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().

Upvotes: 0

Tomer Shetah
Tomer Shetah

Reputation: 8529

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
}

Upvotes: 1

Henrique Goulart
Henrique Goulart

Reputation: 1855

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)

Upvotes: 0

Related Questions