我正在尝试使用Testcontainers库测试一些用doobie开发的SQL语句。详细地说,我使用了以下依赖项:
"org.testcontainers" % "testcontainers" % "1.17.3" % Test,
"org.testcontainers" % "postgresql" % "1.17.3" % Test我的域模型很简单:
final case class Company(id: Int, name: String, description: String)我使用init脚本在PostgreSQL上创建表:
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
"org.scalatest" %% "scalatest" % scalaTestVersion % Test,
"org.typelevel" %% "cats-effect-testing-scalatest" % scalaTestCatsEffectVersion % Test测试代码如下:
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"
}
}
}
}但是,测试的断言失败,出现以下错误,这表明代码没有将任何内容插入数据库。
None was not defined
ScalaTestFailureLocation: com.rockthejvm.board.playground.algebras.CompaniesSpec at (CompaniesSpec.scala:68)我真不明白为什么考试不及格。有谁可以帮我?
发布于 2022-07-09 19:30:12
makePostgres是一个Resource,您可以将它与HikariTransactor组合成transaction Resource。这意味着每次调用transaction.use{ ... }时,都会启动一个新容器,并启动一个新的hikari连接池。当use中的代码完成时,这两个代码都会停止。
因为这两个查询都在不同的transactor.use{ ... }块中执行,所以它们都运行在不同的容器中和不同的连接池上。
相反,您应该确保在整个测试过程中使用相同的资源。
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"
}https://stackoverflow.com/questions/72921826
复制相似问题