1

例如,我有一个简单的提取器Planex.plan 文件字符串,它将它们重新组合在一起。我对它进行了一些单元测试,它们非常彻底地定义了它的行为。这是提取器:

object Planex {
  def apply(metadata: String, plan: String) = {
    String.format("%1$sPlan:\n%2$s", metadata, plan)
  }
  def unapply(str: String) = {
    val ixPlanLabel = str indexOf "Plan:"
    when(ixPlanLabel>=0) {
      (str take ixPlanLabel, (str drop (ixPlanLabel+5)).trim)
    }
  }
}

我有一个Actor使用这个的。

class PlanRepo(env: {
  val jsonFormats: Formats
  val load: () => String
  val planTarget: String => Unit
}) extends Actor {
  implicit val jsonFormats = env.jsonFormats
  def receive = {
    case (metaData: String, plan: Plan) => {
      val s = Planex(metaData,write(plan))
      env.planTarget(s)
    }
    case r: PlanRequest => {
      val Planex(metaData, planStr) = env.load()
      self.channel ! (metaData, read[Plan](planStr))
    }
  }
}

从我对 PlanRepo 的测试中,我能够传递它的所有依赖项,除了Planex. 为此,我仍在使用具体提取器对象。所以我的 repo 测试实际上也在测试Planex. 有没有解决的办法?

我在定义本文档的 json 部分的层次结构的一组嵌套案例类中遇到了类似的问题 - 我无法将它们彼此分开。

4

1 回答 1

2

在特征中定义提取器,然后Planex扩展该特征而不是直接实现它们。

trait PlanexExtractor {
  def apply(metadata: String, plan: String) = {
    String.format("%1$sPlan:\n%2$s", metadata, plan)
  }
  def unapply(str: String) = {
    val ixPlanLabel = str indexOf "Plan:"
    when(ixPlanLabel>=0) {
      (str take ixPlanLabel, (str drop (ixPlanLabel+5)).trim)
    }
  }
}

object Planex extends PlanexExtractor

或者,如果您愿意,可以在 trait 中定义接口,并在扩展该 trait 的对象中实现它。

trait PlanexAPI {
  def apply(metadata: String, plan: String): String
  def unapply(str: String): Option[String]
  }
}

object Planex extends PlanexAPI {
  def apply(metadata: String, plan: String) = {
    String.format("%1$sPlan:\n%2$s", metadata, plan)
  }
  def unapply(str: String) = {
    val ixPlanLabel = str indexOf "Plan:"
    when(ixPlanLabel>=0) {
      (str take ixPlanLabel, (str drop (ixPlanLabel+5)).trim)
    }
  }
}
于 2011-08-13T15:47:20.850 回答