我有一个案例课
case class InputCriteria(a: Int) {
val b: Int = config.getInt("some path")
}
如何模拟这种情况下的类并覆盖b的值?
答案 0 :(得分:4)
从圣杯faq:
我可以模拟val / lazy val吗?
否,Scala编译器不允许使用def覆盖val,因此使用ScalaMock是不可能的。我们正在寻找一个可能的ScalaMock未来版本的选项是scala.meta,但这尚未对我们想要的所有构建目标可用。如果可以的话,最好设计一个带有def的特征并模拟它。具体的实现仍然可以使用val覆盖该def以给出不变的行为。
如果将案例类别更改为trait
,则可以用proxy.MockFactory覆盖val
。
如果您将val
更改为def
,则可以使用普通模拟覆盖。
您还可以使用拉曼答案中的方法,因此,除非您想让班级final
是可行的解决方案。
但是我认为您真正应该做的只是创造特质:
trait InputCriteria {
def b: Int
}
然后实现它:
case class ConfigDrivenInputCriteria(config: Config) extends InputCriteria {
override val b: Int = config.getInt("some path")
}
然后在测试中,您可以重新实现它:
val testInputCritria = new InputCriteria {
override def b: Int = 4
}
但如果 InputCriteria 中有很多字段,可能会有些笨拙,但是在这种情况下,您也可以模拟它:
val inputCriteria = stub[InputCriteria]
(inputCriteria.b _).when().returns(100)
接口+实现方法使您能够轻松测试代码。您还可以在实现类时决定您的属性是 defs , vals 还是 lazy vals 。
答案 1 :(得分:2)
尝试一下:
object abc extends App {
case class A() {
val x = 6
}
val a: A = new A() {
override val x = 9
}
println(A().x, a.x)
}