首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用测试容器测试Doobie解释器

使用测试容器测试Doobie解释器
EN

Stack Overflow用户
提问于 2022-07-09 13:39:32
回答 1查看 170关注 0票数 0

我正在尝试使用Testcontainers库测试一些用doobie开发的SQL语句。详细地说,我使用了以下依赖项:

代码语言:javascript
复制
"org.testcontainers" % "testcontainers" % "1.17.3" % Test,
"org.testcontainers" % "postgresql"     % "1.17.3" % Test

我的域模型很简单:

代码语言:javascript
复制
final case class Company(id: Int, name: String, description: String)

我使用init脚本在PostgreSQL上创建表:

代码语言:javascript
复制
CREATE TABLE companies (
  id serial NOT NULL,
  name text NOT NULL,
  description text
);

ALTER TABLE companies
ADD CONSTRAINT pk_companies PRIMARY KEY (id);

我正在尝试开发一个验证插入新Company的集成测试。我用的是scalatest

代码语言:javascript
复制
"org.scalatest" %% "scalatest"                     % scalaTestVersion           % Test,
"org.typelevel"  %% "cats-effect-testing-scalatest" % scalaTestCatsEffectVersion % Test

测试代码如下:

代码语言:javascript
复制
class CompaniesSpec extends AsyncFreeSpec with AsyncIOSpec with BeforeAndAfter with Matchers {

  private val transactor: Resource[IO, Transactor[IO]] = for {
    postgres <- makePostgres
    ce       <- ExecutionContexts.fixedThreadPool[IO](1)
    xa <- HikariTransactor.newHikariTransactor[IO](
      "org.postgresql.Driver",
      postgres.getJdbcUrl,
      postgres.getUsername,
      postgres.getPassword,
      ce
    )
  } yield xa

  private def makePostgres =
    Resource.make(IO {
      val container: PostgreSQLContainer[Nothing] =
        new PostgreSQLContainer().withInitScript("sql/companies.sql")
      container.start()
      container
    })(c => IO(c.stop()))

  "Companies algebra " - {
    "should create a new Company" in {
      (for {
        companyId    <- transactor.use { xa =>
          sql"INSERT INTO companies (name, description) VALUES ('My Company', 'My Company Description')"
            .update
            .withUniqueGeneratedKeys[Int]("id")
            .transact(xa)
        }
        maybeCompany <- transactor.use { xa =>
          sql"SELECT * FROM companies WHERE id = $companyId"
            .query[Company]
            .option
            .transact(xa)
        }
      } yield maybeCompany)
        .asserting { company =>
          company shouldBe defined
          company.get.name shouldBe "My Company"
          company.get.description shouldBe "My Company Description"
        }
    }
  }
}

但是,测试的断言失败,出现以下错误,这表明代码没有将任何内容插入数据库。

代码语言:javascript
复制
None was not defined
ScalaTestFailureLocation: com.rockthejvm.board.playground.algebras.CompaniesSpec at (CompaniesSpec.scala:68)

我真不明白为什么考试不及格。有谁可以帮我?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-09 19:30:12

makePostgres是一个Resource,您可以将它与HikariTransactor组合成transaction Resource。这意味着每次调用transaction.use{ ... }时,都会启动一个新容器,并启动一个新的hikari连接池。当use中的代码完成时,这两个代码都会停止。

因为这两个查询都在不同的transactor.use{ ... }块中执行,所以它们都运行在不同的容器中和不同的连接池上。

相反,您应该确保在整个测试过程中使用相同的资源。

代码语言:javascript
复制
transactor.use { xa =>
  for {
    companyId    <-
      sql"INSERT INTO companies (name, description) VALUES ('My Company', 'My Company Description')"
        .update
        .withUniqueGeneratedKeys[Int]("id")
        .transact(xa)
    maybeCompany <- 
      sql"SELECT * FROM companies WHERE id = $companyId"
        .query[Company]
        .option
        .transact(xa)
  } yield maybeCompany
}
.asserting { company =>
  company shouldBe defined
  company.get.name shouldBe "My Company"
  company.get.description shouldBe "My Company Description"
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72921826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档