尝试在 scalatest 中使用 beforeAll 时没有启动应用程序
There is no started application when trying to use beforeAll in scalatest
在我的测试中class我想在所有测试开始之前做一些事情,所以我做了这样的事情:
class ApplicationSpec extends FreeSpec with OneServerPerSuite with BeforeAndAfterAll {
override protected def beforeAll(): Unit = {
doSomething()
}
"Application Test" - {
"first test" in {
...
}
}
}
但是我得到一个错误:
Exception encountered when invoking run on a nested suite - There is
no started application java.lang.RuntimeException: There is no started application
它只有在我尝试在测试中使用 doSomething() 时才有效...
我该如何解决这个问题?
谢谢!
我假设 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 仓库:
//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()
,这将调用 BeforeAndAfterAll
中的 run
方法它将执行 beforeAll()
,然后调用 FreeSpec
的 super.run()
,这将执行测试。
在我的测试中class我想在所有测试开始之前做一些事情,所以我做了这样的事情:
class ApplicationSpec extends FreeSpec with OneServerPerSuite with BeforeAndAfterAll {
override protected def beforeAll(): Unit = {
doSomething()
}
"Application Test" - {
"first test" in {
...
}
}
}
但是我得到一个错误:
Exception encountered when invoking run on a nested suite - There is no started application java.lang.RuntimeException: There is no started application
它只有在我尝试在测试中使用 doSomething() 时才有效...
我该如何解决这个问题?
谢谢!
我假设 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 仓库:
//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()
,这将调用 BeforeAndAfterAll
中的 run
方法它将执行 beforeAll()
,然后调用 FreeSpec
的 super.run()
,这将执行测试。