【问题标题】:How to set an in memory test database for my Scala Play2 CRUD application?如何为我的 Scala Play2 CRUD 应用程序设置内存测试数据库?
【发布时间】:2016-03-17 09:36:50
【问题描述】:

我将继续探索 Play 框架及其相关组件。我一开始就使用 CRUD 应用程序的模板连接到 PostgreSQL 数据库。它将应用程序拆分为模型、存储库、控制器和视图。这很好用。 现在,我正在尝试使用 Specs2 为这个应用程序创建一些测试。更准确地说,我正在尝试测试存储库。定义如下:

package dal
import javax.inject.{ Inject, Singleton }
import play.api.db.slick.DatabaseConfigProvider
import slick.driver.JdbcProfile

import models.Cat
import scala.concurrent.{ Future, ExecutionContext }

@Singleton
class CatRepository @Inject() (dbConfigProvider: DatabaseConfigProvider)(implicit ec: ExecutionContext) {
...
}

我想设置一个内存数据库,它将在所有测试之前创建(模式、演变),在所有测试之后销毁,填充(数据,可能使用直接 SQL)并在每个测试周围刷新。我想将它传递给我的存储库实例,然后我将使用它来执行我的测试。喜欢:

val repo = new CatRepository(inMem_DB)

那么我该怎么做: 1)创建这个数据库并应用进化? 也许:

trait TestDB extends BeforeAfterAll {
    var database: Option[Database] = None

    def before = {
        database = Some(Databases.inMemory(name = "test_db"))
        database match {
            case Some(con) => Evolutions.applyEvolutions(con)
            case _ => None
        }
        println("DB READY")
    }

    def after = {
        database match {
            case Some(con) => con.shutdown()
            case _ => None
        }
    }
}

当我需要使用 db 时,使用 var 并始终进行“匹配/大小写”并不方便。我想有更好的方法来做到这一点......

2) 在每个测试周围填充和刷新? 我应该像 BeforeAfterAll 一样创建一个扩展 Around 的特征吗?

3) 从数据库中创建这些 play.api.db.slick.DatabaseConfigProvider ? 任何链接显示如何做到这一点?

我发现很少有例子可以通过运行 FakeApplication 来解决这个问题,但我认为有一种方法可以以某种方式将 db 传递给正在运行的应用程序之外的此类存储库对象..?

感谢您的帮助。 干杯!

【问题讨论】:

    标签: scala unit-testing playframework-2.0 slick specs2


    【解决方案1】:

    您可以使用lazy valAfterAll 进行数据库设置/拆卸,然后使用BeforeAfterEach 进行每个示例:

    trait TestDB extends AfterAll with BeforeAfterEach {
      lazy val database: Database = 
        Databases.inMemory(name = "test_db")
    
      def afterAll = 
        database.shutdown
    
    
      def before = 
        database.populate
    
      def after =
        datbase.clean
    }
    

    【讨论】:

    • 非常感谢@Eric,这对我的第一个问题很有帮助。但是,我仍然坚持其他两个问题。实际上,即使我尝试使用 FakeApplication 工具,我仍然不知道如何填充测试数据库并将其传递到我的存储库进行测试。
    • 这就是before 方法的目的。此方法将在每次测试之前调用,因此您可以使用它来填充数据库。然后它是可访问的,因为它是所有规范可见的lazy val。但是,您需要在规范中使用 sequential 参数以确保每个测试都与另一个测试保持隔离。
    • 是的,我在上一条消息中并不清楚。我确实了解 before、after 和 afterAll 在这里的作用。句柄“数据库”允许直接访问内存中的数据库,我应该也可以在那里应用进化。我最大的问题来自试图将此数据库传递到存储库进行测试。在生产中,DatabaseConfigProvider 是自动注入的。如何替换/覆盖/绕过此机制以提供内存数据库进行测试?
    • 看起来我完全偏离了这种方法。 Databases.inMemory 似乎与使用 slick 作为数据库访问层不兼容。所以在这里我回到了 0。我跟着这个:playframework.com/documentation/2.4.x/PlaySlick。我通过依赖注入配置了 2 个数据库(默认和测试)和 DatabaseConfig,就像所示的那样。我如何才能指明使用哪一种进行测试?
    • 也许您可以使用 Guice 准确地注入您需要的测试数据库:stackoverflow.com/questions/34159857/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    • 2013-06-10
    • 2016-01-15
    • 2018-09-16
    相关资源
    最近更新 更多