运维开发网

Scala:模仿和蛋糕模式

运维开发网 https://www.qedev.com 2020-05-28 10:16 出处:网络 作者:运维开发网整理
我一直在尝试采用蛋糕图案,但我遇到了适应这种编程风格的困难,特别是在单元测试方面. 假设我有以下业务对象: trait Vet { def vaccinate(pet: Pet) } trait PetStore { this: Vet => def sell(pet: Pet) { vaccinate(pet) // do some other stuff } }
我一直在尝试采用蛋糕图案,但我遇到了适应这种编程风格的困难,特别是在单元测试方面.

假设我有以下业务对象:

trait Vet {
  def vaccinate(pet: Pet)
}

trait PetStore { this: Vet =>
  def sell(pet: Pet) {
    vaccinate(pet)
    // do some other stuff
  }
}

现在,我想测试PetStore,同时嘲笑Vet的功能.如果我正在使用组合,我正在创建一个模拟[Vet]并将其传递给PetStore构造函数,然后像我们在Java世界中一样编程模拟.但是,我没有提到人们如何用蛋糕模式来做这件事情.

一种可能的解决方案是根据预期用途在每个测试用例上实施疫苗接种(),但这不允许我验证嘲讽是否被正确调用,不允许我使用匹配器等.

所以 – 人们如何使用蛋糕模式与模拟对象?

我在阅读这篇博文后开始使用蛋糕模式: https://github.com/precog/staticsite/blob/master/contents/blog/Existential-Types-FTW/index.md该方法与大多数Cake Pattern文章不同,因为存在类型使用而不是自我类型.

我一直在使用这种模式几个月,似乎很好,因为我可以指定一个模拟,当我想.它确实有更多的依赖注入感觉,但它具有所有的好处,让你的代码的特点.

我使用存在类型的你的问题的混搭版本将是这样的:

case class Pet(val name: String)
trait ConfigComponent {
  type Config
  def config: Config
}

trait Vet {
  def vaccinate(pet: Pet) = {println ("Vaccinate:" + pet)}
}

trait PetStoreConfig {
  val vet: Vet
}
trait PetStore extends ConfigComponent {

    type Config <: PetStoreConfig

    def sell(pet: Pet) {
      config.vet.vaccinate(pet)
      // do some other stuff
    }
}

你可以把它放在你的应用程序中

class MyApp extends PetStore with PetStoreConfig {

  type Config = MyApp
  def config = this  

  val vet = new Vet{}
  sell(new Pet("Fido"))

}

scala> new MyApp
Vaccinate:Pet(Fido)
res0: MyApp = MyApp@668dd96c

您可以通过创建VetLike的实例来单独测试组件,还可以使用您的PetStore测试创建VetLike的模拟.

//Test VetLike Behavior
scala> val vet = new Vet{}
scala> vet.vaccinate(new Pet("Fido"))
Vaccinate:Pet(Fido)


//Test Petstore Behavior

class VetMock extends Vet {
   override def vaccinate(pet: Pet) = println("MOCKED")
}

class PetStoreTest extends PetStore with PetStoreConfig {
   type Config = PetStoreTest
   def config = this

   val vet = new VetMock
   val fido = new Pet("Fido")
   sell(fido)
}

scala> new PetStoreTest
MOCKED
0

精彩评论

暂无评论...
验证码 换一张
取 消