模拟案例类进行测试

时间:2019-05-20 11:43:09

标签: scala scalatest scalamock

我有一个案例课

case class InputCriteria(a: Int) {
   val b: Int = config.getInt("some path")
}

如何模拟这种情况下的类并覆盖b的值?

2 个答案:

答案 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)
}