2

ScalaTest トレイトの BeforeAndAfterEach をオーバーライドして、すべてのテストでその機能を 1 回実装したいと考えています。最後にコンパイルしましたが、理由がわかりません。

trait MySetup extends BeforeAndAfterEach {
  this : org.scalatest.BeforeAndAfterEach with org.scalatest.Suite =>
  var service: String = _

  abstract override def beforeEach(): Unit = {
    service = "apa"
    super.beforeEach()
  }

  abstract override def afterEach(): Unit = {
    service = ""
  }
}

それを機能させたのは次の行でした:

  this : org.scalatest.BeforeAndAfterEach with org.scalatest.Suite =>

BeforeAndAfterEach 実装の冒頭で見つけてコピーしました。

それは何をし、なぜそれが必要なのですか?

アップデート:

これはよりシンプルなバージョンです。

trait MySetup extends FlatSpec with BeforeAndAfterEach {
  var service: String = _

  override def beforeEach {
    service = "apa"
    super.beforeEach
  }

  override def afterEach {
    service = ""
    super.afterEach
  }
}
4

3 に答える 3

5

BeforeAndAfterEach には Suite の自己型があります。つまり、BeforeAndAfterEach は Suite を拡張する型にのみ混在させることができます。ScalaTest は、最初にプライマリ スイート タイプを選択し、その後でミックスイン動作を選択することを望んでいます。

自己型宣言はサブトレイトに継承されないため、自己型を再宣言する必要があります。

次の質問には、自己型とサブ特性の間にいくつかのトレードオフがあります:自己型と特性サブクラスの違いは何ですか?

ScalaTest 設計の背景については、http ://www.artima.com/scalazine/articles/selfless_trait_pattern.html を参照してください。

于 2011-07-03T18:40:35.860 に答える
1

おそらく MySetup を書く方法は次のとおりです。

import org.scalatest.Suite
import org.scalatest.BeforeAndAfterEach

trait MySetup extends BeforeAndAfterEach { this: Suite =>

  var service: String = _

  abstract override def beforeEach(): Unit = {
    service = "apa"
    super.beforeEach()
  }

  abstract override def afterEach(): Unit = {

    try {
      super.afterEach() // To be stackable, must call super.afterEach
    }
    finally {
      service = ""
    }
  }
}

そうすれば、自己型はあまり邪魔になりません。マイクの答えは正しいです。アイデアは、特性をスタックできるようにすることです。したがって、必要に応じて、このように複数の特性を異なる順序で混在させることができます。別の関連記事は「スタック可能な特性パターン」です。

http://www.artima.com/scalazine/articles/stackable_trait_pattern.html

関連する Scaladoc セクションの例も役立つ場合があります。

http://www.scalatest.org/scaladoc-1.6.1/org/scalatest/FlatSpec.html#composingFixtures

super.afterEach も呼び出すことに注意してください。スタック可能にするには、beforeEach と afterEach の両方で super を呼び出す必要があります。super.afterEach が例外で爆発した場合でも、このトレイトの after 動作が得られるように、私は試してみました。(ただし、スイートはその時点でいずれにせよ中止される可能性が高いため、この場合はおそらく問題にはなりません。しかし、一般的には良い考えです。)

于 2011-07-03T21:22:11.243 に答える
-1

これは、依存性注入の Scala 構文です。

this: <dependency> =>

それは文字通りthis特性が特性に依存することを意味し<dependency>ます。詳細については、この記事を参照してください。

于 2011-07-03T19:00:02.963 に答える