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?
If you have a "complex dependency" of mocks, then I would suggest that instead of val
s these mocks were def
s 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.