0
votes

Say I have trait:

trait A {
    def a(): Boolean
}

And mock + testcase:

trait Fixture {
    val mockA = mock[A]
    (mockA _).returns(true)
}

"mock must return true" in new Fixture {
    mockA() must equal(true)
}

Now, I want to re-mock the value to false for a single test in the same test suite

trait ChildFixture extends Fixture {
    (mockA _).returns(false) // this obviously doesn't work
}
"mock must return false" in new ChildFixture {
    mockA() must equal(false)
}

This is a very simplified example, I have a complex dependency chain of mocking fixtures. The obvious answer is to extract the mocking code for mockA into another fixture and then mix into the ones that should be true, then make a new Fixture for the specific test that should be false. Only issue is this is an onerous process given my test code. It is also possible to manually mock the return with an anonymous class and a var, but this does not seem very elegant and loses the function of Scala mock call validation.

Is it possible to restub an already-mocked object for a single test?

1
How do your fixtures work? Why something like override val isn't an option?Mateusz Kubuszok
@MateuszKubuszok updated the question with the fixture setup. I didn't think of override val but it unfortunately does not work. It causes a null pointer exception in the mock setup code in the parent fixture.TTT

1 Answers

1
votes

If you have a "complex dependency" of mocks, then I would suggest that instead of vals these mocks were defs which you could safely override, because you would call assign the result to val manually after potential rewrite. Also, all changes to such mock could be made in a block of code:

trait A {
  def a(): Boolean
}

trait B {
  def b(): B
}

trait Fixture {
  def createMockA(): A = {
    val mocked = mock[A]
    (mocked.a _) returns true
    mocked
  }

  def createMockB(): B = {
    val mocked = mock[B]
    (mocked.b _) returns createMockA
    mocked
  }
}

trait FixtureChild extends Fixture {
  override def createMockA(): A = {
    val mocked = mock[A]
    (mocked.a _) returns false
    mocked
  }
}

"value must be overriden" in new FixtureChild {
  val b = createMockB()
  b.b().a() must beFalse
}

However if you have a "complex dependency chain of a mocking fixtures" I would treat that as a red flag that the code needs refactoring.