【问题标题】:Unit test: mock nested scala val单元测试:模拟嵌套的 scala val
【发布时间】:2019-04-05 19:36:35
【问题描述】:

我有两个案例类AAHelper

case class AHelper(data: String) {
  def getData() = {...} // Complex operation inside
}

case class A(data1: String, data2: String) {
  private val aHelper = AHelper(data2)    // AHelper instance
  def getData() = {data1 + aHelper.getData; ...} // Complex operation inside
}

A 具有 AHelper 的实例作为其成员之一。

我只想为 A 编写单元测试,模拟 AHelper

Scala 版本:2.11

【问题讨论】:

  • 真实场景中,A和AHelper类都是复杂代码
  • 为什么不能做一个简单的类?这会很容易
  • @RamanMishra 制作一个简单的类有助于解决这个问题吗?
  • 是的,那么您可以覆盖 getData 并返回您想要的任何内容,只需在测试用例中创建一个新对象 A 并覆盖 getData。因为无论如何 case 类都用于模式匹配,所以我们应该避免在 case 类中使用数据函数。
  • 我不想覆盖 a.getData。我想覆盖 aHelper.getData。 a.getData 在实际案例中做得更多

标签: scala unit-testing scalatest


【解决方案1】:

helper应该是一个参数:

case class A(data1: String, data2: String)(aHelper: AHelper = AHelper(data2))

现在在你的测试中,你可以这样做:A("foo", "bar")(mock[AHelper])

如果你不喜欢第二个参数列表,有几个选项:

让它隐含:

case class A(data1: String, data2: String)(implicit aHelper: AHelper = AHelper(data2))

这使您可以仅使用 new A("foo", "bar") 创建实例,而无需在末尾添加 ()

或者,创建一个伴随对象:

 object A {
   def apply(data1: String, data2: String): A = A(data1, data2)(AHelper(data2))
 }

注意另外,需要单元测试的涉及逻辑的案例类是......不寻常的。案例类意味着只是数据的哑持有者,如果你愿意的话,是一个带有命名字段的元组。您应该考虑将您的逻辑从这些类中分离出来,或者将它们改为“常规”(非大小写)类。

例如:

case class A1(data: String)
case class A2(data1: String, data2: A1)

trait AHelper {
  def getData(a1: A1)
}

class  AReader(helper: AHelper) {
  def getData(a: A2) = a.data1 + helper.getData(a.data2))
}

现在,如何正确测试这一点已经没有问题了,对吧?

【讨论】:

  • 感谢您的解释。我是斯卡拉的新手。给我一些时间来理解伴生对象和其他概念,我会回来接受这个答案
  • “需要单元测试的涉及逻辑的案例类是......不寻常的”这对我来说是一个重要的声明。是你的经验还是一般规则?
  • @user811602 两者都是 :)
猜你喜欢
  • 2021-09-10
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 2015-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-09
相关资源
最近更新 更多