Tyler
Tyler

Reputation: 18177

Asynchronous assertion is not firing in scalatest

I am trying to write a test that just checks to see that the correct database is setup, but the assertion is never firing, and everything ends successfully (even though it should fail):

import anorm._
import org.scalatestplus.play._
import play.api.db.DB

class Housekeeping extends PlaySpec with OneServerPerSuite {

    // Make sure the test database is loaded
    "test connection to test database" in {

        DB.withConnection { implicit connection =>
            SQL("SELECT * FROM accounts WHERE ID = 1").withResult(res => {
                val row = res.head.row
                val name = row.asMap("accounts.name")
                println(name)               // Prints to console
                name mustEqual "this should fail"
                println("HERE")             // Never prints to console
            })
        }
    }
}

Console:

[info] Housekeeping:
[info] - application - Creating Pool for datasource 'default'
tyler
[info] - test connection to test database
[info] - application - Shutting down connection pool.

I'm not sure why nothing is happening, since I am getting the name fine from the database. I couldn't find any documentation about performing asynchronous tests, which I think may be part of the problem.

Upvotes: 3

Views: 500

Answers (1)

dk14
dk14

Reputation: 22374

Something like this can help:

import org.scalatest._
import concurrent.AsyncAssertions

import anorm._
import org.scalatestplus.play._
import play.api.db.DB

class Housekeeping extends PlaySpec with OneServerPerSuite with AsyncAssertions {

    // Make sure the test database is loaded
    "test connection to test database" in {
        val w = new Waiter
        DB.withConnection { implicit connection =>
            SQL("SELECT * FROM accounts WHERE ID = 1").withResult(res => {
                val row = res.head.row
                val name = row.asMap("accounts.name")
                println(name)               // Prints to console
                w { name mustEqual "this should fail" }
                w.dismiss()
                println("HERE")            
            })
        }
        w.await()
    }
}

Your problem was that scalatest didn't receive the exception fired by mustEqual as it was thrown asynchronously.

Practically Waiter is a kind of wrapper around Promise (so you have to do dismiss() in order to complete it) and w.await() just waits for it and redirects the exception from w{...} to the scalatest's thread.

Upvotes: 3

Related Questions