在使用
在playframework中运行测试时,我有进化问题未知数据类型:" JSONB"我的H2DbConnector看起来像这样:
import entities.StubData._
import org.scalatest.{BeforeAndAfterAll, FunSuite}
import play.api.db.DBApi
import play.api.db.evolutions.Evolutions
import play.api.inject.guice.GuiceApplicationBuilder
trait H2DbConnector extends FunSuite with BeforeAndAfterAll {
val appBuilder = new GuiceApplicationBuilder()
.configure(configuration)
val injector = appBuilder.injector
lazy val databaseApi = injector.instanceOf[DBApi]
override def beforeAll() = {
Evolutions.applyEvolutions(databaseApi.database("default"))
}
override def afterAll() = {
Evolutions.cleanupEvolutions(databaseApi.database("default"))
}
}
在application.test.conf中
slick.dbs.default.driver = "slick.driver.H2Driver$"
slick.dbs.default.db.driver = "org.h2.Driver"
slick.dbs.default.db.url = "jdbc:h2:mem:play;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=FALSE"
我在evolutions 2.sql文件中有一条有问题的行
ALTER TABLE "Messages" ADD COLUMN "metaJson" JSONB NULL;
当我运行dao测试时出现错误,如
2017-12-21 16:08:40,409 [error] p.a.d.e.DefaultEvolutionsApi - Unknown data type: "JSONB"; SQL statement:
ALTER TABLE "Messages" ADD COLUMN "metaJson" JSONB NULL [50004-194] [ERROR:50004, SQLSTATE:HY004]
[info] OptoutsDaoTest *** ABORTED ***
[info] play.api.db.evolutions.InconsistentDatabase: Database 'default' is in an inconsistent state![An evolution has not been applied properly. Please check the problem and resolve it manually before marking it as resolved.]
[info] at play.api.db.evolutions.DatabaseEvolutions.$anonfun$checkEvolutionsState$3(EvolutionsApi.scala:285)
[info] at play.api.db.evolutions.DatabaseEvolutions.$anonfun$checkEvolutionsState$3$adapted(EvolutionsApi.scala:270)
[info] at play.api.db.evolutions.DatabaseEvolutions.executeQuery(EvolutionsApi.scala:317)
[info] at play.api.db.evolutions.DatabaseEvolutions.checkEvolutionsState(EvolutionsApi.scala:270)
[info] at play.api.db.evolutions.DatabaseEvolutions.evolve(EvolutionsApi.scala:239)
[info] at play.api.db.evolutions.Evolutions$.applyEvolutions(Evolutions.scala:193)
[info] at H2DbConnector.beforeAll(H2DbConnector.scala:15)
[info] at H2DbConnector.beforeAll$(H2DbConnector.scala:14)
[info] at OptoutsDaoTest.beforeAll(OptoutsDaoTest.scala:5)
[info] at org.scalatest.BeforeAndAfterAll.liftedTree1$1(BeforeAndAfterAll.scala:212)
[info] ...
你可以帮我解决这个问题吗?
答案 0 :(得分:5)
我最近也遇到了 JSONB和H2 的问题。我通过创建JSONB到JSON的别名解决了该问题,并使其仅在H2上的测试配置文件中运行。
CREATE TYPE "JSONB" AS json;
这不是JSONB,但JSONB与JSON的区别(至少在postgres中)本质上是阅读的表现,对于测试目的,它实际上并不重要(如此)。
也许这个例子也有帮助:
这是使用flyway的示例。创建一个sql条目,以在/ resources / db / tests上为jsonb创建一个别名类型,该别名类型仅在测试配置文件上运行。
我们正在使用spring,所以这是 application.yml 上的入口:
spring:
profiles: mytest
datasource:
continueOnError: false
url: jdbc:h2:mem:myapp-db;DB_CLOSE_ON_EXIT=FALSE;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE
flyway:
enabled: true
locations: classpath:db/migration, classpath:db/tests
[......]
这是$ {project.dir} / resources / db /
的列表这就是魔术:
在文件的内容中,我创建了一个名为JSONB的类型,该类型基本上是JSON类型的别名。注意:就我所知,大写是必需的(特别是在创建表时引用大写),因为H2似乎会自动将类型名称更改为大写:
CREATE TYPE "JSONB" AS json;
以下是创建这种类型的表的示例:
CREATE TABLE "XXX" (
id BIGSERIAL PRIMARY KEY,
my_json_column_name JSONB NOT NULL
);
在休眠状态下,我使用hibernate-types52中的JsonBinaryType类型。有关此link的更多信息。
@Data
@TypeDef(name = "jsonb", typeClass = com.vladmihalcea.hibernate.type.json.JsonBinaryType.class)
@Entity(name = "XXX")
@Table(name = "XXX")
public class XXX {
@Type(type = "jsonb")
@Column(name = "my_json_column_name", nullable = false)
private String myJsonColumnName;
//OR
@Type(type = "jsonb")
@Column(name = "my_json_column_name", nullable = false)
private List<MYCustomTypeThatMatchesJsonObject> myJsonColumnName;
}
我希望它可以帮助某人。它对我有用。
更新于2020-07-13
我停止在项目中使用H2,开始使用testcontainers。设置非常容易,您可以在实际的数据库环境中进行测试。
答案 1 :(得分:3)
答案 2 :(得分:1)
当您连接到某物时,您不能使用PostgreSQL进行单元测试,单元测试只能中继内存测试,因为它会被您的构建触发,并且构建服务器不太可能访问任何物理数据库,您可能需要另一种方式来模拟数据并避免从数据库访问数据,或者将数据类型更改为string []并封装为产生JSON