2

我想覆盖 ScalaTest 特征 BeforeAndAfterEach 以便为我的所有测试实现一次。最后我得到了编译,但我不明白为什么。

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 因异常而爆炸,您仍然会得到此特征的后续行为。(尽管那时您的套件可能会中止,所以在这种情况下它可能无关紧要。但总的来说这是一个好主意。)

于 2011-07-03T21:22:11.243 回答
-1

这是依赖注入的 Scalas 语法。

this: <dependency> =>

这意味着字面上this的特质取决于<dependency>特质。阅读这篇文章了解更多。

于 2011-07-03T19:00:02.963 回答