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!

+3


source to share


1 answer


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.

+2


source







All Articles