Knows Not Much
Knows Not Much

Reputation: 31576

Writing UnitTests for Slick DAO

I wrote a simple Slick DAO and I am trying to write unit test for the DAO

This is the code for my DAO

package tables

import slick.driver.H2Driver.api._
import scala.concurrent.ExecutionContext.Implicits.global
import play.api.Play.current

case class Person(id: Int, firstname: String, lastname: String)

class People(tag: Tag) extends Table[Person] (tag, "PEOPLE") {
  def id = column[Int]("PEOPLE_ID", O.PrimaryKey)
  def firstname = column[String]("PEOPLE_FIRSTNAME")
  def lastname = column[String]("PEOPLE_LASTNAME")
  def * = (id, firstname, lastname) <> (Person.tupled, Person.unapply _)
}

object PeopleDAO {
  val people = TableQuery[People]
  val db = Database.forConfig("h2mem1")
  db.run(people.schema.create)

  def loadDummyData() {
    try {
      db.run(people ++= Seq(
        Person(1, "test1", "user1"),
        Person(2, "test2", "user2"),
        Person(3, "test3", "user3")))
    } finally db.close
  }

  def create(input : Person) {
    try {
      db.run(people ++= Seq(input))
    } finally db.close
  }

  def getAll() {
    people.map(x => x)
  }

  def getById(id: Int) {
    people.filter(x => x.id === id)
  }
}

and this is the unit test

import org.specs2.mutable._
import tables._

class DBOTest extends Specification {
  "A DBO " should {
    "load test data " in {
      val result = PeopleDAO.loadDummyData()
      result.map{ x =>
        x.foreach { y => 
          println(s" number of rows $y")
          y equalTo 3
        }
      }
    }
  }
}

Now my code compiles fine. But when I run the unit test by activator test I get cryptic error message

[info] Compiling 3 Scala sources to /Users/abhi/ScalaProjects/MyPlay1/target/scala-2.11/test-classes...
[error] /Users/abhi/ScalaProjects/MyPlay1/test/DBOTest.scala:8: type mismatch;
[error]  found   : => result.type (with underlying type => result.type)
[error]  required: ?{def map(x$1: ? >: <error> => <error>): ?}
[error] Note that implicit conversions are not applicable because they are ambiguous:
[error]  both method lazyParameter in trait LazyParameters of type [T](value: => T)org.specs2.control.LazyParameter[T]
[error]  and method theValue in trait MustExpectations1 of type [T](t: => T)org.specs2.matcher.MustExpectable[T]
[error]  are possible conversion functions from => result.type to ?{def map(x$1: ? >: <error> => <error>): ?}
[error]       result.map{ x =>
[error]       ^
[error] one error found
[error] (test:compileIncremental) Compilation failed
[error] Total time: 5 s, completed Jun 26, 2015 2:50:09 PM
Mohitas-MBP:MyPlay1 abhi$ 

Upvotes: 0

Views: 674

Answers (1)

bjfletcher
bjfletcher

Reputation: 11518

I see two problems here:

  1. result isn't a valid "result" for Specs2, you need to use Specs2's await feature to block until this Future completes;

  2. the db.run(people.schema.create) is run in the constructor of the PeopleDAO that really you should wrap in an Await.result to ensure that it's ready before you start running the tests.

Upvotes: 1

Related Questions