在我的测试课中我想在所有测试开始之前做一些事情,所以我做了类似的事情:
class ApplicationSpec extends FreeSpec with OneServerPerSuite with BeforeAndAfterAll {
override protected def beforeAll(): Unit = {
doSomething()
}
"Application Test" - {
"first test" in {
...
}
}
}
但是我收到了错误:
在嵌套套件上调用run时遇到异常 - 有 没有启动应用程序java.lang.RuntimeException:没有启动的应用程序
只有当我尝试在测试中使用doSomething()时它才有效...
我该如何解决这个问题?
谢谢!
答案 0 :(得分:3)
我假设doSomething()
执行一些依赖于应用程序状态的操作。
试试这个:
class ApplicationSpec extends FreeSpec with BeforeAndAfterAll with OneServerPerSuite{
override protected def beforeAll(): Unit = {
doSomething()
}
"Application Test" - {
"first test" in {
...
}
}
}
问题是你可能mixin linearization in wrong order
。
在BeforeAndAfterAll之前的mixin
OneSerPerSuite中,调用super.run()
的顺序相反,导致在应用程序启动之前调用beforeAll()
。
来自两个项目的git repo:
//BeforeAndAfterAll
abstract override def run(testName: Option[String], args: Args): Status = {
if (!args.runTestInNewInstance && (expectedTestCount(args.filter) > 0 || invokeBeforeAllAndAfterAllEvenIfNoTestsAreExpected))
beforeAll()
val (runStatus, thrownException) =
try {
(super.run(testName, args), None)
}
catch {
case e: Exception => (FailedStatus, Some(e))
}
...
}
//OneServerPerSuite
abstract override def run(testName: Option[String], args: Args): Status = {
val testServer = TestServer(port, app)
testServer.start()
try {
val newConfigMap = args.configMap + ("org.scalatestplus.play.app" -> app) + ("org.scalatestplus.play.port" -> port)
val newArgs = args.copy(configMap = newConfigMap)
val status = super.run(testName, newArgs)
status.whenCompleted { _ => testServer.stop() }
status
} catch { // In case the suite aborts, ensure the server is stopped
case ex: Throwable =>
testServer.stop()
throw ex
}
}
首先将OneServerPerSuite
特征放在最后,它将first initialize the application
,然后调用super.run()
,这将调用run
内的BeforeAndAfterAll
方法执行beforeAll()
,然后调用将执行测试的super.run()
FreeSpec
。