scalaslickscalatestslick-3.0

Async before and after for creating and dropping scala slick tables in scalatest


I'm trying to figure out a way to have async before and after statements where the next test cases aren't run until the completion of the action inside of the test case. In my case, it is the creating and dropping a table inside of a database

  val table = TableQuery[BlockHeaderTable]
  val dbConfig: DatabaseConfig[PostgresDriver] = DatabaseConfig.forConfig("databaseUrl")
  val database: Database = dbConfig.db
  before {
    //Awaits need to be used to make sure this is fully executed before the next test case starts
    //TODO: Figure out a way to make this asynchronous 
    Await.result(database.run(table.schema.create), 10.seconds)
  }

  "BlockHeaderDAO" must "store a blockheader in the database, then read it from the database" in {
    //...
  }

  it must "delete a block header in the database" in {
    //...
  }

  after {
    //Awaits need to be used to make sure this is fully executed before the next test case starts
    //TODO: Figure out a way to make this asynchronous
    Await.result(database.run(table.schema.drop),10.seconds)
  }

Is there a simple way I can remove these Await calls inside of my before and after functions?


Solution

  • Unfortunately, @Jeffrey Chung's solution hanged for me (since futureValue actually awaits internally). This is what I ended up doing:

    import org.scalatest.{AsyncFreeSpec, FutureOutcome}
    import scala.concurrent.Future
    
    class TestTest extends AsyncFreeSpec /* Could be any AsyncSpec. */ {
      // Do whatever setup you need here.
      def setup(): Future[_] = ???
      // Cleanup whatever you need here.
      def tearDown(): Future[_] = ???
      override def withFixture(test: NoArgAsyncTest) = new FutureOutcome(for {
        _ <- setup()
        result <- super.withFixture(test).toFuture
        _ <- tearDown()
      } yield result)
    }