10

Cake パターンを採用しようとしてきましたが、特に単体テストに関して、このプログラミング スタイルに適応するのに苦労しています。

次のビジネス オブジェクトがあるとします。

trait Vet {
  def vaccinate(pet: Pet)
}

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

ここで、Vet の関数をモックアウトしながら、PetStore をテストしたいと思います。コンポジションを使用していた場合、モック [Vet] を作成して PetStore コンストラクターに渡し、Java の世界で行うようにモックをプログラミングしていました。ただし、人々がケーキのパターンでこれを行う方法についての参照は見つかりません。

考えられる解決策の 1 つは、予想される使用法に従って各テスト ケースに vaccinate() を実装することですが、これでは、モックが適切に呼び出されたことを確認できず、マッチャーなどを使用できません。

では、モック オブジェクトで Cake パターンをどのように使用しているのでしょうか。

4

4 に答える 4

4

いい質問です。私たちは、少なくとも私たちが慣れ親しんだ方法とはまったく異なる方法で、それを行うことはできないという結論に達しました. モックの代わりにスタブを使用して、スタブを簡単に混ぜることができます。しかし、これはモックを使用するよりも手間がかかります。

2 つの Scala チームがあり、1 つのチームはモックの代わりにスタブを使用してケーキ パターンを採用し、もう 1 つのチームはクラスと依存性注入に固執しました。今は両方を試しましたが、テストが簡単なため、モックを使用した DI を好みます。そして間違いなく読みやすいです。

于 2013-04-29T15:20:06.060 に答える
2

「Cake Pattern」モジュールの単体テストを目的として、Scalatest で Scalamock を使用する方法を見つけました。

最初は(これを含め)多くの問題がありましたが、以下に示す解決策は受け入れられると思います。ご不明な点がございましたら、お気軽にお問い合わせください。

これは私があなたの例を設計する方法です:

trait VetModule {
  def vet: Vet
  trait Vet {
    def vaccinate(pet: Pet)
  }
}

trait PetStoreModule {
  self: VetModule =>
  def sell(pet: Pet)
}

trait PetStoreModuleImpl extends PetStoreModule {
  self: VetModule =>
  def sell(pet: Pet) {
    vet.vaccinate(pet)
    // do some other stuff
  }
}

テストは次のように定義されます。

class TestPetstore extends FlatSpec with ShouldMatchers with MockFactory {

  trait PetstoreBehavior extends PetStoreModule with VetModule {

    object MockWrapper {
      var vet: Vet = null
    }

    def fixture = {
      val v = mock[Vet]
      MockWrapper.vet = v
      v
    }

    def t1 {
      val vet = fixture
      val p = Pet("Fido")
      (vet.vaccinate _).expects(p)
      sell(p)
    }

    def vet: Vet = MockWrapper.vet
  }

  val somePetStoreImpl = new PetstoreBehavior with PetStoreModuleImpl
  "The PetStore" should "vaccinate an animal before selling" in somePetStoreImpl.t1
}

val vet = fixtureこのセットアップを使用すると、作成するすべてのテストで呼び出さなければならないという「欠点」があります。一方、テストの別の「実装」を簡単に作成できます。

val someOtherPetStoreImpl = new PetstoreBehavior with PetStoreModuleOtherImpl
于 2013-08-19T00:11:39.650 に答える
1

これは古い質問ですが、将来の読者のために回答を追加しています。私はこのSOの投稿 - How to use mocks with the Cake Pattern - が同じことを尋ね、答えていると信じています。

私はウラジミール・マトヴェーエフによって与えられた答えにうまく従いました(これは執筆時点での最高の答えでした

于 2016-03-30T16:19:03.473 に答える