作为一个例子,我有一个简单的提取器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
的单独测试行为。有办法解决这个问题吗?
我对一组嵌套的case类有类似的问题,这些case类定义了本文档的json部分的层次结构 - 我将它们彼此分开时遇到了麻烦。
答案 0 :(得分: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 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)
}
}
}