【问题标题】:Change jdbcURL in fakeApplication in unit test在单元测试中更改 fakeApplication 中的 jdbcURL
【发布时间】:2022-10-22 08:55:38
【问题描述】:

我是 scala 的新手,我将它与 Playframework 一起使用来构建 API。

我有多个 docker 容器(API、DB)。此外,还有一个模块,其中指定了 DB 配置。在此配置中,我在 setJdbcUrl 中使用 docker 容器名称 db。 在 docker 容器中运行时一切正常。

但是,我有一个测试路线的健康检查单元测试。 此测试失败,因为它无法识别 URL(如预期的那样),但我不确定是否有办法更新测试中的假应用程序以使用正确的 URL。

模块

class ReadWriteDB extends ScalaModule {

  @Singleton
  @Provides
  @Named("db.sql.readwrite.quill.context")
  def quillContext(): PostgresJdbcContext[SnakeCase.type] = {
    val ds = new HikariDataSource(DBConnectionConfig.hikariConfig())
    QuillFactory.create(ds, Duration("2m"))
  }

object DBConnectionConfig {
  def hikariConfig(): HikariConfig = {
    val config = new HikariConfig
    config.setDriverClassName("org.postgresql.Driver")
    config.setJdbcUrl("jdbc:postgresql://db:5432/postgres")
//    config.setJdbcUrl("jdbc:postgresql://localhost:5432/postgres")
//    with the commented config, unit test runs correctly
    config.setUsername(...)
    config.setPassword(...)
    config
  }
}

单元测试

class HealthCheckSpec extends PlaySpec with GuiceOneAppPerTest with Injecting {

  "HealthCheck status" should {
    "reply from the router" in {
      // can I edit app to use a different URL here? 
      val request = FakeRequest(GET, "/status")
      val home = route(app, request).get

      status(home) mustBe OK
      contentAsString(home) must include("API is running!")
    }
  }
}

控制器

@Singleton
class HealthCheck @Inject()(val controllerComponents: ControllerComponents) extends BaseController {

  def check(): Action[AnyContent] = Action {
    Ok("API is running!\n")
  }
}

任何指导方针将不胜感激。

【问题讨论】:

  • 你能显示响应“/状态”的控制器的代码吗?它如何访问数据库?有没有可以用模拟注入的服务特征,而不是尝试与真实数据库对话?

标签: postgresql scala playframework guice


【解决方案1】:

您拥有所需的所有工具。我会将对象变成一个类并像您在 quillContext 中一样使用@provides 和@singleton,我还将把行为提取到一个特征中,并有一个方法来进行健康检查:

trait DBObjectConfig {
    def hikariConfig(): HikariConfig
    def isOK() :Boolean
}

@provides
class RealDBConnection extends DBObjectConfig {
  def hikariConfig(): HikariConfig = {
    val config = new HikariConfig
    config.setDriverClassName("org.postgresql.Driver")
    config.setJdbcUrl("jdbc:postgresql://db:5432/postgres")
    config.setJdbcUrl("jdbc:postgresql://localhost:5432/postgres")
    config.setUsername(...)
    config.setPassword(...)
    config
  }

  // todo: make something here that's a reliable test.
  def isOK() :Boolean = {
    Option(hakariConfig.getConnection()).isDefined
  }
}

您的健康检查控制器可以使用 OK() 来查看数据库是否已启动。

然后在您的测试中,使用 Guice(您的测试扩展了注入器?)您应该能够将 DBObjectConfig 的虚假实现绑定到您的应用程序,这将导致您的控制器在测试环境中无法实例化真正的数据库连接:

// inside your tests.

class MockDB extends DBObjectConfig {
    def hikariConfig(): HikariConfig = ??? // implementation not required
    def isOK() :Boolean = true             // fake it being okay.
}

val application = new GuiceApplicationBuilder()
  .overrides(bind[DBObjectConfig].to[MockDB])
  .build()

使用这种通用方法的一些技术应该可以工作。

【讨论】:

    【解决方案2】:

    要实现Health Check,我会推荐Play-Actuator 依赖。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-02
      • 2013-05-11
      • 2011-06-14
      • 2016-04-16
      • 2019-07-22
      • 2015-02-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多