Implementing DAL in Play 2.x (Scala), Slick, ScalaTest

For people in hurry here is the code and the steps.

In continuation of Play 2.x (Scala) is it a Spring MVC contender? – Introduction, in this blog, I will demonstrate how we implement a simple Data Access Layer using ScalaTest and using Behavior Driven Development.

The technical stack I will be using for this demo is Java 7, Play 2.1.0, Scala 2.10.0, Slick 1.0.0, ScalaTest / ScalaMock 3.0, STS IDE for Scala Development, Scala IDE plugin with ScalaTest.

As a first step create a Play project called coffee-example and select the language as Scala as below,

play new coffee-example

Now we need to include these dependencies in Build.scala. In this example, we don’t need ScalaMock but we will still include that dependency as below,

"com.typesafe.slick" %% "slick" % "1.0.0",
...
"org.scalamock" %% "scalamock-scalatest-support" % "3.0" % "test",

Let us convert this project into Eclipse project as below,

play eclipse

Let us open STS IDE and create a DomainTest.scala under test folder. The intent is we create a new CoffeeComponent class and implement a method findById method and pass a Coffee name and return the Coffee object and assert for its price. We also need initialize the data we are supposed to assert.

class DomainSpec extends FunSpec with ShouldMatchers with InitTrait {

  lazy val database = Database.forDataSource(DB.getDataSource())

  describe("Coffee Data Access") {

    it("should find Coffee object for a given Coffee name") {
      running(FakeApplication(additionalConfiguration = inMemoryDatabase())) {
        database withSession {
          init

          val cc = new CoffeeComponentImpl()
          val c = cc.find("Colombian")
          c.first.price should equal(799L)
        }
      }
    }
  }
}

One bug I noticed is, when there are multiple test cases opening database connection it will create Attempting to obtain a connection from a pool that has already been shutdown error.

We create a CoffeeComponent trait and CoffeeComponentImpl, which create basic CRUD operations as below,

trait CoffeeComponent {
  def find(pk: String): Query[Coffees.type, Coffee]
  def findall(pk: String): Query[(Coffees.type, Suppliers.type), (Coffee, Supplier)]
  def list(page: Int, pageSize: Int, orderBy: Int, filter: String): Query[(Coffees.type, Suppliers.type), (Coffee, Supplier)]
  def delete(pk: String): Int
}

class CoffeeComponentImpl extends CoffeeComponent {

  def find(pk: String): Query[Coffees.type, Coffee] = {
    Coffees.findByPK(pk)
  }

  def findall(pk: String): Query[(Coffees.type, Suppliers.type), (Coffee, Supplier)] = {
    Coffees.findAll(pk)
  }

  def list(page: Int, pageSize: Int, orderBy: Int, filter: String): Query[(Coffees.type, Suppliers.type), (Coffee, Supplier)] = {
    Coffees.list(page, pageSize, orderBy, filter)
  }

  def delete(pk: String): Int = {
    find(pk).delete
  }
}

We also need to create the Initialize Data for the test as below,

trait InitTrait {
  def init = {
    val ddl = (Suppliers.ddl ++ Coffees.ddl)

    ddl.drop
    ddl.create
    // Insert some suppliers
    Suppliers.insertAll(
      Supplier(Some(101), "Acme, Inc.", "99 Market Street", "Groundsville", "CA", "95199"))
.....
    Coffees.insertAll(
      Coffee(Some("Colombian"), 101, 799, 0, 0))
}
}

Now run the ScalaTest from Eclipse IDE, you will see something as below,

ScalaTest Coffee Example

ScalaTest Coffee Example

I hope this blog helped you. In the next blog I will demonstrate how we can mock a Controller and test the Controller.

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s