Scala: Easier Tests with Wrapped DB Connection

Play! Framework documentation provides some hints that allow to use in-memory H2 database for unit test with ScalaTest.

There is, for instance, this template:

rt play.api.db.{Database, Databases}

withMyDatabase[T](block: Database => T) = {
tabases.withDatabase(
driver = "com.mysql.jdbc.Driver",
url = "jdbc:mysql://localhost/test",
name = "mydatabase",
config = Map(
  "user" -> "test",
  "password" -> "secret"
)
block)

Which can be used to wrap test code that needs database connection like this:

MyDatabase { database =>
l connection = database.getConnection()
 ...

This solution is fully valid, but I don't like it because there are still some pieces of boilerplate code that need to be added to manage JDBC connections.

I decided to push it a bit further and create this abstract class:

rt java.sql.Connection
rt mypackage.DbCreator
rt org.scalatest.{FlatSpec, Matchers}
rt play.api.db.Databases

ract class DbConnectedTestSuite extends FlatSpec with Matchers {

otected def withInMemoryDb(block : Connection => Unit) = {
// The in-memory database ref will be recreated for each test,
// but it can easily be extracted from here and reused for multiple test cases.
val db = Databases.inMemory("test_db")
val connection = db.getConnection()
try {
  createNewDbSchema(connection)
  block.apply(connection)
} finally {
  connection.close()
  db.shutdown() //
}


ivate def createNewDbSchema(connection: Connection) = {
// Project-dependent code of creation and filling of a test DB, for example:
val dbCreator = new DbCreator(connection)
dbCreator.createSchema()
dbCreator.executeScriptFile("/test-data.sql")



Now I make my test suite inherit from this abstract class and wrap the test code in withInMemoryDb:

s StarsManagerTestSuite extends DbConnectedTestSuite {

he test" should "produce expected results" in {
withInMemoryDb { connection =>
  // the code of the test that uses the connection, which does not need to be closed here
  // ...
}



These code examples are coupled with ScalaTest, but indeed this is not at all mandatory and the solution can be applied anywhere else, just by changing the means to access a Connection reference in withInMemoryDb function.

 
 
Tags:  programming scala jdbc tests
Level:  beginner