Как я могу издеваться или заглушать классы и экстракторы в Scala? - PullRequest
1 голос
/ 13 августа 2011

Например, у меня есть простой экстрактор 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.Для этого я все еще использую бетонный экстрактор.Так что мой репо-тест на самом деле также тестирует отдельно протестированное поведение Planex.Есть ли способ обойти это?

У меня есть похожие проблемы с набором вложенных классов case, определяющих иерархию json-части этого документа - у меня возникают проблемы при их отделении друг от друга.

1 Ответ

2 голосов
/ 13 августа 2011

Определите экстракторы в признаке, а затем просто добавьте 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)
    }
  }
}
...