尝试在scalatest中使用beforeAll时,没有启动应用程序

时间:2017-04-27 15:20:37

标签: scala scalatest scalacheck

在我的测试课中我想在所有测试开始之前做一些事情,所以我做了类似的事情:

class ApplicationSpec extends FreeSpec with OneServerPerSuite with BeforeAndAfterAll {

  override protected def beforeAll(): Unit = {
    doSomething()
  }

  "Application Test" - {
    "first test" in {
      ...
    }
  }

}

但是我收到了错误:

  

在嵌套套件上调用run时遇到异常 - 有   没有启动应用程序java.lang.RuntimeException:没有启动的应用程序

只有当我尝试在测试中使用doSomething()时它才有效...

我该如何解决这个问题?

谢谢!

1 个答案:

答案 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