When trying to use beforeAll in scalatest, no app running
in my test class i want to do something before all tests start, so i did something like this:
class ApplicationSpec extends FreeSpec with OneServerPerSuite with BeforeAndAfterAll {
override protected def beforeAll(): Unit = {
doSomething()
}
"Application Test" - {
"first test" in {
...
}
}
}
but I am getting the error:
The exception that is thrown when starting a run in a nested set. There is no application running java.lang.RuntimeException: application not running
it only works if I try to use doSomething () inside tests ...
how can i fix this?
thank!
source to share
I am assuming that it doSomething()
is performing some kind of operation depending on the state of the application.
Try the following:
class ApplicationSpec extends FreeSpec with BeforeAndAfterAll with OneServerPerSuite{
override protected def beforeAll(): Unit = {
doSomething()
}
"Application Test" - {
"first test" in {
...
}
}
}
The problem is that you might mixin linearization in wrong order
. In mixin
OneSerPerSuite, before BeforeAndAfterAll, the order in which it is called super.run()
is reversed, resulting in a call beforeAll()
before the application starts .
From the git repo of two projects:
//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
}
}
So by putting a character at the end OneServerPerSuite
, it will first initialize the application
then call super.run()
which will call the method run
inside BeforeAndAfterAll
, which will execute beforeAll()
and then call super.run()
from FreeSpec
which will execute the tests.
source to share