Reputation: 1295
As an example, I have a simple extractor, Planex
, that takes apart .plan file strings and puts them back together. I have a few unit tests on it that pretty thoroughly define its behavior. Here's the extractor:
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)
}
}
}
I have an Actor
that uses this.
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))
}
}
}
From my tests on PlanRepo, I'm able to pass in all of its dependencies, except for Planex
. For that, I'm still using the concrete extractor object. So my repo test is actually also testing the separately-tested behavior of Planex
. Is there a way around this?
I have similar problems with a set of nested case classes defining the hierarchy of the json part of this document - I'm having trouble separating them from each other.
Upvotes: 1
Views: 834
Reputation: 297265
Define the extractors in a trait, and then just have Planex
extend that trait instead of implementing them directly.
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
Or, if you prefer, define the interface in the trait, and implement it in the object that extends that 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)
}
}
}
Upvotes: 2