尝试在 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(),然后调用 FreeSpecsuper.run(),这将执行测试。