测试Play + Slick应用程序

ped*_*o91 7 testing scala playframework-2.0 slick slick-3.0

我有一个使用Scala Play 2.4.3Play-slick 1.1.0(slick 3.1.0)构建的简单CRUD应用程序,它使用MySQL数据库进行持久存储.

我试图为我的应用程序创建测试,我看到了两个主要选项:

  • 模拟数据库访问,据我所见,需要一些代码更改
  • make tests使用替代数据库(可能在内存H2中).

什么是最好的方法(优势和消极)?

我更喜欢第二种方法,但我在设置测试时遇到了一些困难.

我需要做什么?首先,我认为我需要使用FakeApplication运行测试,对吧?我是否需要任何sbt依赖才能做到这一点?

之后,如何指定使用H2数据库?

nor*_*oru 6

我有同样的斗争,我想出了这样的解决方案(使用第二种方法):

为DAO创建一个上下文来使用:

trait BaseContext{

  def dbName: String

  val dbConfig = DatabaseConfigProvider.get[JdbcProfile](dbName)
  val db = dbConfig.db
  val profile = dbConfig.driver
  val tables = new Tables {  // this is generated by Schema Code Generator
    override val profile: JdbcProfile = dbConfig.driver
  }
}

@Singleton
class AppContext extends BaseContext{
  def dbName = "mysql"  // name in your conf right after "slick.dbs"
}

@Singleton
class TestingContext extends BaseContext{
  def dbName = "h2"
}
Run Code Online (Sandbox Code Playgroud)

然后创建一个模块来绑定注入,并且不要忘记在conf中启用它play.modules.enabled += "your.Module":

class ContextModule(environment: Environment, configuration: Configuration) extends AbstractModule {

  override def configure(): Unit = {
    if (configuration.getString("app.mode").contains("test")) {
      bind(classOf[BaseContext])
          .to(classOf[TestingContext])
    } else {
      bind(classOf[BaseContext])
          .to(classOf[AppContext])
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

并将它注入您创建的每个DAO:

class SomeDAO @Inject()(context: BaseContext){

  val dbConfig = context.dbConfig
  val db = context.db
  val tables = context.tables
  import tables.profile.api._

  def otherStuff....
  // you can call db.run(...), tables.WhateverYourTableIs, tables.TableRowCaseClass, ...
}
Run Code Online (Sandbox Code Playgroud)

最后一步,你的配置文件.在我的情况下,我曾经app.mode标记过环境,并且我.conf对不同的环境使用单独的.原因是,在这些配置中,您必须具有正确的数据库配置.这是样本:

app.mode = "test"

# Database configuration
slick.dbs = {
  # for unit test
  h2 {
    driver = "slick.driver.H2Driver$"
    db = {
      url = "jdbc:h2:mem:test;MODE=MYSQL"
      driver = "org.h2.Driver"
      keepAliveConnection = true
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我很确定我的解决方案不是一个优雅的解决方案,但它可以提供货物.:)欢迎任何更好的解决方案!

  • 以该演示项目为例,它演示了如何在运行时流畅地访问2 DB,而我的主要目标是在测试中使用SAME业务逻辑(一组代码)将mysql替换为h2。这意味着在为实际功能或单元测试进行编码时,我不必关心数据库。那使conf文件成为最好的地方,所以我编写了解决方法。之后,我完全满意,并且没有跟踪最新的视频。如果有更好的方法,请赐教。很长一段时间困扰我。 (2认同)

ped*_*o91 5

我的解决方案是step(Play.start(fakeApp))在每个规格的开头和每个规格step(Play.stop(fakeApp))的末尾添加。

也:

def fakeApp: FakeApplication = {
FakeApplication(additionalConfiguration =
  Map(
    "slick.dbs.default.driver" -> "slick.driver.H2Driver$",
    "slick.dbs.default.db.driver" -> "org.h2.Driver",
    "slick.dbs.default.db.url" -> "jdbc:h2:mem:play"
  ))
Run Code Online (Sandbox Code Playgroud)

}

这是必需的,因为我使用的是play-slick,它需要如下配置:

slick.dbs.default.driver = "slick.driver.MySQLDriver$"
slick.dbs.default.db.driver = "com.mysql.jdbc.Driver"
slick.dbs.default.db.url = "jdbc:mysql://localhost/database"
slick.dbs.default.db.user = "user"
slick.dbs.default.db.password = "password"
Run Code Online (Sandbox Code Playgroud)

有关文档的更多信息