Reputation: 641
I have a case class
case class InputCriteria(a: Int) {
val b: Int = config.getInt("some path")
}
How to mock this case class and override the value of b?
Upvotes: 0
Views: 1870
Reputation: 22625
From scalamock faq:
Can I mock val / lazy val?
No, the Scala compiler will not allow overriding a val with a def, so with ScalaMock this is not possible. An option we are looking at for a possible future version of ScalaMock is scala.meta, but this is not yet available for all build targets we want. If you can, it is better to design a trait with a def and mock that instead. The concrete implementation can still override that def with a val to give invariant behaviour.
If you change your case class to trait
you'd be able to override val
with proxy.MockFactory.
If you changed you val
to def
you'd be able to override with plain mock.
You could also use the approach from Raman's answer, so unless you would want to make your class final
it's working solution.
But what you should really do in my opinion is just creating trait:
trait InputCriteria {
def b: Int
}
and then implementing it:
case class ConfigDrivenInputCriteria(config: Config) extends InputCriteria {
override val b: Int = config.getInt("some path")
}
Then in test you could just reimplement it:
val testInputCritria = new InputCriteria {
override def b: Int = 4
}
but it might be a little bit clunky if you've got a lot of fields in InputCriteria, but in that case you could also mock it:
val inputCriteria = stub[InputCriteria]
(inputCriteria.b _).when().returns(100)
Interface + implementation approach gives you the ability to test your code easily. You can also decide in implementing class if your properties should be defs, vals or lazy vals.
Upvotes: 5
Reputation: 2686
try this:
object abc extends App {
case class A() {
val x = 6
}
val a: A = new A() {
override val x = 9
}
println(A().x, a.x)
}
Upvotes: 2