0

I am facing a problem of database clean-up after each test when using scalatest with Slick.

Here is code of the test:

class H2DatabaseSpec extends WordSpec with Matchers with ScalaFutures with BeforeAndAfter {
  implicit override val patienceConfig = PatienceConfig(timeout = Span(5, Seconds))

  val h2DB: H2DatabaseService = new H2DatabaseService
  var db: Database = _

  before {
    db = Database.forConfig("h2mem1")
    h2DB.createSchema.futureValue
  }

  after {
    db.shutdown.futureValue
  }

  "H2 database" should {
    "query a question" in {
      val newQuestion: QuestionEntity = QuestionEntity(Some(1L), "First question")
      h2DB.insertQuestion(newQuestion).futureValue

      val question = h2DB.getQuestionById(1L)

      question.futureValue.get shouldBe newQuestion
    }
  }

  it should {
    "query all questions" in {
      val newQuestion: QuestionEntity = QuestionEntity(Some(2L), "Second question")
      h2DB.insertQuestion(newQuestion).futureValue

      val questions = h2DB.getQuestions

      questions.futureValue.size shouldBe 1
    }
  }
}

Database service is just invoking run method on defined database:

class H2DatabaseService {

  val db = Database.forConfig("h2mem1")

  val questions = TableQuery[Question]

  def createSchema =
    db.run(questions.schema.create)

  def getQuestionById(id: Long): Future[Option[QuestionEntity]] =
    db.run(questions.filter(_.id === id).result.headOption)

  def getQuestions: Future[Seq[QuestionEntity]] =
    db.run(questions.result)

  def insertQuestion(question: QuestionEntity): Future[Int] =
    db.run(questions += question)
}

class Question(tag: Tag) extends Table[QuestionEntity](tag, "QUESTION") {
  def id = column[Option[Long]]("QUESTION_ID", O.PrimaryKey, O.AutoInc)
  def title = column[String]("TITLE")

  def * = (id, title) <> ((QuestionEntity.apply _).tupled, QuestionEntity.unapply)
}

case class QuestionEntity(id: Option[Long] = None, title: String) {
  require(!title.isEmpty, "title.empty")
}

And the database is defined as follows:

h2mem1 = {
  url = "jdbc:h2:mem:test1"
  driver = org.h2.Driver
  connectionPool = disabled
  keepAliveConnection = true
}

I am using Scala 2.11.8, Slick 3.1.1, H2 database 1.4.192 and scalatest 2.2.6.

Error that appears when tests are executed is Table "QUESTION" already exists. So it looks like shutdown() method has no effect at all (but it is invoked - checked in debugger).

Anybody knows how to handle such scenario? How to clean-up database properly after each test?

Marek J
  • 1,364
  • 8
  • 18
  • 33

1 Answers1

0

Database has not been correctly cleaned-up because of invoking the method on different object.

H2DatabaseService has it's own db object and the test it's own. Issue was fixed after refactoring H2 database service and invoking:

after {
  h2DB.db.shutdown.futureValue
}
Marek J
  • 1,364
  • 8
  • 18
  • 33