麻烦设置在内存数据库中进行单元测试2.4在Slick 3中

时间:2016-01-18 15:54:21

标签: scala playframework slick specs2

我正在尝试在内存中设置h2 db,然后使用Slicks功能创建必要的表,以便在我的play specs2测试中使用。我创建了一个覆盖WithApplication的抽象类,然后覆盖around方法,但是当createTables函数尝试运行预测试时出现错误。我怀疑我没有正确传递数据库连接/配置,但我得到的错误不是很有帮助。我通过包装播放Databases.withInMemory函数

来创建数据库

这是我的db帮助对象

package testHelpers

import models.VisitorImages._
import models.VisitorRegistrations._
import models.VisitorSignatures._
import models.VisitorStatuses._
import models.Visitors._
import org.specs2.execute.{Result, AsResult}
import play.api.test.WithApplication
import play.api.{Logger, Application, Play}
import play.api.db.slick.DatabaseConfigProvider
import play.api.db.{Databases, Database}
import slick.backend.DatabaseConfig
import slick.profile.{BasicProfile, RelationalProfile}

import scala.concurrent.Await
import scala.concurrent.duration.Duration

object TestDatabase {
  class testDbProvider extends DatabaseConfigProvider {
    def get[P <: BasicProfile]: DatabaseConfig[P] = {
      DatabaseConfigProvider.get("default")(Play.current)
    }
  }

  def startTestDb[T](block: Database => T) = {
    Databases.withInMemory(
      name = "testDB",
      urlOptions = Map(
        "MODE" -> "MSSQLServer"
      ),
      config = Map(
        "logStatements" -> true
      )
    )(block)
  }

  abstract class WithTestDb extends WithApplication((TestApplication.application)) {
    val profile = slick.driver.H2Driver
    import profile.api._

    override def around[T: AsResult](t: => T): Result = super.around {
      setupData()
      t
    }

    val allTables = (VisitorSignatures.schema ++ VisitorImages.schema ++ Visitors.schema ++ VisitorStatuses.schema ++ VisitorRegistrations.schema
    ).create

    /** Create all tables in database */
    def createTables = {
      Logger.info(s"yadda yadda yadda")
      val db = new testDbProvider().get.db
      Await.result(db.run(Visitors.schema.create), Duration.Inf)
      Logger.info(s"variable user is blah blah")
    }

    /** Delete all tables in database */
    def drop = {
//      allTables.drop
    }

    def setupData() {
      // setup data
      createTables
    }
  }

}

以下是我尝试使用它的方式

package unit.models

import models.VisitorRegistrations._
import play.api.{Play, db}
import play.api.db.slick.DatabaseConfigProvider
import play.api.test.{WithApplication, PlaySpecification}
import play.db.NamedDatabase
import providers.VisitorRegistrationProvider
import repositories.VisitorRegistrationRepository
import slick.driver.JdbcProfile
import slick.lifted.TableQuery
import testHelpers.TestDatabase.WithTestDb
import testHelpers.{Inject, TestApplication, TestDatabase}

import scala.concurrent.Await
import scala.concurrent.duration.Duration

class VisitorRegistrationsSpec extends PlaySpecification with Inject {
  val vrp = inject[VisitorRegistrationProvider]
  val db = vrp.dbConfig.db

  import vrp.dbConfig.driver.api._

  TestDatabase.startTestDb { database =>
    "VisitorResgistrations" should {
      "save a vr" in new WithTestDb {

        val res = Await.result(db.run(VisitorRegistrations.result), Duration.Inf)

        res must equalTo(1)
      }
    }

  }
}

这是我得到的错误

[info] VisitorResgistrations should
[error]   ! save a vr
[error]    null (Database.scala:61)
[error] testHelpers.TestDatabase$WithTestDb.createTables(Database.scala:61)
[error] testHelpers.TestDatabase$WithTestDb.setupData(Database.scala:72)
[error] testHelpers.TestDatabase$WithTestDb$$anonfun$around$1.apply(Database.scala:50)
[error] play.api.test.WithApplication$$anonfun$around$2.apply(Specs.scala:39)
[error] play.api.test.WithApplication$$anonfun$around$2.apply(Specs.scala:39)
[error] play.api.test.PlayRunners$class.running(Helpers.scala:42)
[error] play.api.test.Helpers$.running(Helpers.scala:363)
[error] play.api.test.WithApplication.around(Specs.scala:39)
[error] testHelpers.TestDatabase$WithTestDb.around(Database.scala:49)
[error] play.api.test.WithApplication.delayedInit(Specs.scala:36)
[error] testHelpers.TestDatabase$WithTestDb.<init>(Database.scala:45)
[error] unit.models.VisitorRegistrationsSpec$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anon$1.<init>(VisitorRegistrationsSpec.scala:30)
[error] unit.models.VisitorRegistrationsSpec$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3.apply(VisitorRegistrationsSpec.scala:30)
[error] unit.models.VisitorRegistrationsSpec$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3.apply(VisitorRegistrationsSpec.scala:30)

1 个答案:

答案 0 :(得分:1)

副手,看起来好像有初始化订单问题。尝试将班级val更改为lazy valdef

相关问题