很少有人对ScalaTest中beforeAll构造的有用性感到困惑

时间:2016-02-20 18:59:52

标签: scala scalatest

关于scalaTest中'beforeAll'等方法的有用性,我有更多的哲学混淆。 我一直在寻找答案为什么甚至需要像beforeAll这样的结构?我确实理解为什么要做出这个设计决定但却无法思考它。有人可以帮忙吗?

e.g。 按照在线教程的建议方式,

class TestExample extends FunSuite with BeforeAndAfterAll {
   private var _tempDir: File = _
   protected def tempDir: File = _tempDir

 override def beforeAll(): Unit = {
  super.beforeAll()
  _tempDir = Utils.createTempDir(namePrefix = this.getClass.getName)
  }

  test("...") {
   // using the variable in the function
  }
 } 

VS

class TestExample extends FunSuite with BeforeAndAfterAll {
   private val tempDir: File = Utils.createTempDir(namePrefix = 
   this.getClass.getName) 
  }

  test("...") {
   // Use the initialized variable here.
 } 

2 个答案:

答案 0 :(得分:3)

如果你要在afterAll中进行清理,我认为在beforeAll中进行设置是对称的。此外,如果你需要做一些不涉及初始化实例变量的副作用,那么可以进入beforeAll。但是,在你给出的示例中,在所有测试初始化​​实例变量之前,你没有在afterAll中进行任何清理以及所有你正在做的事情,我将使用普通的初始化。

val初始化程序和beforeAll之间的另一个区别是val初始化程序在实例化类时发生,而beforeAll稍后发生,当实例执行时。如果要延迟初始化直到运行类,可以使用延迟val。

答案 1 :(得分:0)

值得注意的一点是,某些运行程序(例如ScalaTest ant任务和Intellij IDEA)将在运行任何测试之前实例化所有测试实例。如果您的设置代码碰巧与任何全局变量或外部状态交互,那么您可能希望将这些交互推迟到测试运行之前。

作为一个简单的(人为)示例,假设您的测试代码包括

Object Singleton {
  var foo = ""
}

,您有两个测试类:

class Test1 extends FunSuite {
  Singleton.foo = "test1"

  test("...") {
    Singleton.foo should be("test1")
  }
}

class Test1 extends FunSuite {
  Singleton.foo = "test2"

  test("...") {
    Singleton.foo should be("test2")
  }
}

如果在运行任何测试之前都实例化了两个类,则两个测试中的至少一个将失败。相反,如果将初始化工作推迟到beforeAll,您将不会在测试之间看到相同的干扰。