模拟案例 class 进行测试
Mocking a case class for testing
我有案例class
case class InputCriteria(a: Int) {
val b: Int = config.getInt("some path")
}
如何模拟这种情况 class 并覆盖 b 的值?
试试这个:
object abc extends App {
case class A() {
val x = 6
}
val a: A = new A() {
override val x = 9
}
println(A().x, a.x)
}
来自 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.
如果您将大小写 class 更改为 trait
,您可以使用 proxy.MockFactory.
覆盖 val
如果您将 val
更改为 def
,您将能够使用普通模拟进行覆盖。
您也可以使用 Raman 的回答中的方法,因此除非您想让 class 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)
接口+实现方法使您能够轻松测试代码。您还可以在实施 class 时决定您的属性是否应为 defs、vals 或 lazy vals.
我有案例class
case class InputCriteria(a: Int) {
val b: Int = config.getInt("some path")
}
如何模拟这种情况 class 并覆盖 b 的值?
试试这个:
object abc extends App {
case class A() {
val x = 6
}
val a: A = new A() {
override val x = 9
}
println(A().x, a.x)
}
来自 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.
如果您将大小写 class 更改为 trait
,您可以使用 proxy.MockFactory.
val
如果您将 val
更改为 def
,您将能够使用普通模拟进行覆盖。
您也可以使用 Raman 的回答中的方法,因此除非您想让 class 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)
接口+实现方法使您能够轻松测试代码。您还可以在实施 class 时决定您的属性是否应为 defs、vals 或 lazy vals.