2016-12-29 52 views
1

我正在this github project使用播放2.5.10和3.1.1油滑(这个问题可以有再现运行sbt test但可以also be checked directly in travis CI)。我使用Postgres数据库配置default进行开发和生产。然后在内存数据库中使用名为test的H2进行测试。所述default数据库在conf/application.conf配置而test数据库在conf/application.test.conf配置。测试Scala Play + Slick:为什么选择错误的数据库?

问题是,对于测试,我初始化名称为test的数据库,但使用GuiceApplicationBuilder构建的应用程序仍在拾取default之一。

这行是我build.sbt拿起测试配置:

javaOptions in Test += "-Dconfig.file=conf/application.test.conf" 

,这是该文件的内容:

include "application.conf" 

slick.dbs { 
    test { 
    driver="slick.driver.H2Driver$" 
    db.driver="org.h2.Driver" 
    db.url="jdbc:h2:mem:test;MODE=PostgreSQL" 
    db.username="sa" 
    db.password="" 
    } 
} 

DaoFunSpec基类看起来是这样的:

package dao 

import org.scalatest.{BeforeAndAfterAll, FunSpec} 
import org.scalatestplus.play.OneAppPerSuite 
import play.api.Application 
import play.api.db.evolutions.Evolutions 
import play.api.db.DBApi 

abstract class DaoFunSpec extends FunSpec with OneAppPerSuite with BeforeAndAfterAll { 
    lazy implicit val db = app.injector.instanceOf[DBApi].database("test") 

    override def beforeAll() { 
    Evolutions.applyEvolutions(db) 
    } 

    override def afterAll() { 
    Evolutions.cleanupEvolutions(db) 
    } 

    def userDao(implicit app: Application) = { 
    Application.instanceCache[UserDao].apply(app) 
    } 
} 

注行app.injector.instanceOf[DBApi].database("test")但STIL l Play试图连接到default数据库。

回答

3

好你的问题是有点不同(或者也许有点出乎意料)。这是使你的头痛行:

dbApi.databases().foreach(runEvolutions) 

其在:ApplicationEvolutions.scala:42

这也可能是不言自明的:)

不过问题是更多地参与。你实际上是两个数据库,在测试环境中(defaulttest)。现在这导致了几个问题 - 你在上面看到了其中的一个问题(每个问题都会尝试进化)。另一种是,如果你想使用不同的名称DB,你不能只是注入类似的东西:

class UserDao @Inject()(protected val dbConfigProvider: DatabaseConfigProvider) 

相反,你需要使用(AFAIR):

class UserDao @Inject()(@NamedDatabase("test") protected val dbConfigProvider: DatabaseConfigProvider) 

但在这种情况下,你测试变得更加复杂。

这将是所有简单得多,如果:

1)你会提取通用配置common.conf

2)你会改变你的application.conf到这样的事情:

include "common.conf" 

slick.dbs { 
    default { 
    driver="slick.driver.PostgresDriver$" 
    db.driver="org.postgresql.Driver" 
    db.url="jdbc:postgresql://localhost:5432/exampledb?searchpath=public" 
    db.user="postgres" 
    db.password="postgres" 
    } 
} 

3)您可以将application.test.conf更改为如下所示:

include "common.conf" 

slick.dbs { 
    default { 
    driver="slick.driver.H2Driver$" 
    db.driver="org.h2.Driver" 
    db.url="jdbc:h2:mem:test;MODE=PostgreSQL" 
    db.username="sa" 
    db.password="" 
    } 
} 

现在唯一的是你应该有一套进化(default),这实际上并不坏,因为它会确保你的测试数据库与你的生产数据库同步(至少在结构上)。

这不是上述是唯一的解决方案。你仍然可以有两个不同名称的数据库配置;您需要在这种情况下在您的Guilce module中做一些重新映射(然后您将有一个模块用于生产,另一个用于测试 - 它们可以相互继承并仅覆盖某些内容 - 例如,将test db代入缺省位置一)。这基本上是一个品味问题。

+0

嗨帕维尔!再次感谢你!好点!但它仍然让我面对2.sql与H2不兼容的问题。这就是为什么我需要单独的测试数据库,所以它会有它自己的evolutions文件夹......我已经搜索了play.evolutions。*带有前缀的参数以改变进化的根,但是没有。这个前缀只存在于测试API'Evolutions.withEvolutions(db,ClassLoaderEvolutionsReader.forPrefix(“conf/test /”))中',但是这被触发得太晚或根本没有。 –

+0

哦...对。由于数据库的差异,没有注意到你有两种不同的演化路径。对。在上述情况下,可能无法工作。我相信你提到的关于阻止进化的另一个问题可以解决这个问题。 请记住,从长远来看,有两条不同的进化路径(test + prod)可能会证明是麻烦的......(但是这可能会对postgres vs embeded H2的运行测试的优缺点加以衡量)。 –

+0

嗨,Pawel,谢谢,非常正确!我决定使用Postgres进行测试。原因有两点:最好在数据库中测试应用程序将最终部署,并且使用Postgres更容易解决数据库问题,即通过连接任何客户端并在H2中运行选择,而在H2中是一个大问题与Squirrel连接...... Ah和另一个为什么选择Postgres的重要原因,Travis CI可以自动部署并运行postgres实例进行单元测试,我把它全部用在github中。 –

相关问题