【问题标题】:play framework use in memory h2 database for unit tests播放框架在内存 h2 数据库中用于单元测试
【发布时间】:2015-04-06 20:50:48
【问题描述】:

我正在尝试配置我的 play 框架应用程序,以便它在运行时使用 mysql 数据库和用于测试的内存数据库。 当我运行测试时,它连接到 mysql 数据库而不是内存数据库。 有人知道为什么吗?

这是我的配置:

db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://localhost/communityRoots?characterEncoding=UTF-8"
db.default.user=root
db.default.password= ""

db.test.driver=org.h2.Driver
db.test.url="jdbc:h2:mem:play;MODE=MYSQL"
db.test.user=sa
db.test.password=""

这是我的测试:

running(fakeApplication(inMemoryDatabase("test")), new Runnable() {
        public void run() {
            new User("bob@gmail.com", "Bob", "secret").save();
            assertNotNull(User.authenticate("bob@gmail.com", "secret"));
            assertNull(User.authenticate("bob@gmail.com", "badpassword"));
            assertNull(User.authenticate("tom@gmail.com", "secret"));
        }
    });

【问题讨论】:

  • 另一种好方法是在 application.conf 中将 h2 用于 DEV 和 TEST,在生产模式下仅使用单独的 application-prod.conf 文件使用 MySQL
  • 是的,我认为这将是不合适的解决方案。希望有一种更简单/更清洁的方法来做到这一点。谢谢
  • 附带说明:我使用 MariaDB4j 作为嵌入式数据库进行测试。它是一个真正的 MySQL 兼容数据库,而不是 H2 不完整的 MySQL 模式。 github.com/vorburger/MariaDB4j
  • @Ciaran0 你是怎么让它最终工作的?

标签: java mysql database junit playframework


【解决方案1】:

来自我正在开发的实际应用程序:

import play.api.inject.bind
import org.scalatest.mock.MockitoSugar
import play.api.Application
import play.api.inject.guice.GuiceApplicationBuilder
import database.AccountDAO
import play.api.Configuration
import play.api.Mode


class AccountDAOSpec extends Specification with MockitoSugar { // we add mockito to show that you can also bind your mocks


val companyAccountDAOMock = mock[CompanyAccountDAO] // let us create a company account DAO mock

  def app = new GuiceApplicationBuilder() // you create your app
    .configure(
      Configuration.from(
        Map( // a custom configuration for your tests only
          "slick.dbs.default.driver" -> "slick.driver.H2Driver$",
          "slick.dbs.default.db.driver" -> "org.h2.Driver",
          "slick.dbs.default.db.connectionPool" -> "disabled",
          "slick.dbs.default.db.keepAliveConnection" -> "true",
          "slick.dbs.default.db.url" -> "jdbc:h2:mem:test",
          "slick.dbs.default.db.user" -> "sa",
          "slick.dbs.default.db.password" -> "")))
    .bindings(bind[AccountDAO].to[AccountDAOImpl]) // here you can define your bindings for an actual implementation (note the use of square brackets)
    .bindings(bind[CompanyAccountDAO].to(companyAccountDAOMock)) // or bind to your mock (note the use of parentheses)
    .in(Mode.Test)
    .build()


  "AccountDAO" should {

    "throw an Exception when adding a user with an invalid data" in new WithApplication(app) { // here you can use the application you just created, it uses the db you defined for your tests

      val app2dao = Application.instanceCache[AccountDAO]
      val accountDAO = app2dao(app) // with this you get the DAO injected

      accountDAO.addAccount(testAccount).run must throwAn[Exception] 
    }
  }
}

【讨论】:

    【解决方案2】:

    您应该删除“测试”。 因此,您的第一行应该是:

    running(fakeApplication(inMemoryDatabase()), new Runnable() { 
        //test specific code
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-30
      • 1970-01-01
      • 1970-01-01
      • 2011-10-19
      • 1970-01-01
      • 2011-12-20
      • 2018-07-16
      • 1970-01-01
      相关资源
      最近更新 更多