是否有嵌入式PostgreSql,以便我们可以对PostgreSql驱动的应用程序进行单元测试?
由于PostgreSql有一些方言,因此使用嵌入式PostgreSql本身比其他嵌入式数据库更好。
嵌入式并不一定意味着它必须嵌入JVM进程中。它也不一定需要使用内存中持久性。它应该由依赖关系管理(Maven,Gradle)自动加载,这样Unit测试就可以在每台机器上运行,而无需安装和配置本地PostgreSQL服务器。
答案 0 :(得分:45)
这是一个“嵌入式”PostgresSQL服务器,专为从Java进行单元测试而设计:
https://github.com/yandex-qatools/postgresql-embedded
嵌入式postgresql将为单元测试中运行postgres二进制文件提供一种平台中立的方式。大部分代码都是从Flapdoodle OSS's embed process
制作的
答案 1 :(得分:34)
不,没有嵌入式PostgreSQL,就像进程内可加载的数据库一样。 PostgreSQL是面向流程的;每个后端都有一个线程,它会生成多个进程来完成工作。它作为一个图书馆没有意义。
The H2 database支持a limited subset of the PostgreSQL SQL dialect以及使用PgJDBC驱动程序。
你可以做的是initdb
a new temporary database,在随机端口上用pg_ctl
启动它,这样它就不会与其他实例发生冲突,运行测试,然后使用{ {1}}停止它并最终删除临时数据库。
我强烈建议您在非默认端口上运行临时postgres ,这样就不会冒险在运行测试的计算机上与任何本地安装的PostgreSQL发生冲突
(是“嵌入式PostgreSQL在ecpg意义上,基本上是嵌入在C 源代码中的PostgreSQL 客户端基于预处理程序的C语言扩展。它仍然需要一个正在运行的服务器,它使用起来有点讨厌,而不是真正推荐的。它主要是为了让从其他各种数据库中移植更容易。)
答案 2 :(得分:19)
我尝试了@btiernay(yandex-qatools)建议的项目。我花了好几天的时间,没有任何冒犯,它是过度设计的解决方案,在我的情况下不起作用,因为我想从内部存储库下载二进制文件而不是去公共互联网。理论上它支持它,但实际上它不支持它。
我最终使用otj-pg-embedded,它就像一个魅力。在评论中提到过,所以我想我也会在这里提到它。
我将它用作独立的数据库,而不是通过规则进行单元测试和本地开发。
<强>相关性:强>
<dependency>
<groupId>com.opentable.components</groupId>
<artifactId>otj-pg-embedded</artifactId>
<version>0.7.1</version>
</dependency>
<强>代码:强>
@Bean
public DataSource dataSource(PgBinaryResolver pgBinaryResolver) throws IOException {
EmbeddedPostgres pg = EmbeddedPostgres.builder()
.setPgBinaryResolver(pgBinaryResolver)
.start();
// It doesn't not matter which databse it will be after all. We just use the default.
return pg.getPostgresDatabase();
}
@Bean
public PgBinaryResolver nexusPgBinaryResolver() {
return (system, machineHardware) -> {
String url = getArtifactUrl(postgrePackage, system + SEPARATOR + machineHardware);
log.info("Will download embedded Postgre package from: {}", url);
return new URL(url).openConnection().getInputStream();
};
}
private static String getArtifactUrl(PostgrePackage postgrePackage, String classifier) {
// Your internal repo URL logic
}
答案 3 :(得分:3)
如果您希望从Integration(或类似的)测试套件中运行postgres的进程内版本,postgresql-embedded对我来说运行正常。
我写了一个small maven plugin,它可以用作postgresql-embedded的分叉版本的maven包装器。
答案 4 :(得分:3)
您可以使用PostgreSQL的container实例。
由于旋转容器只需几秒钟,因此对单元测试而言应该足够好。
此外,如果您需要保留数据,例如为了调查,您不需要保存整个容器,只需保存可以映射到容器外部的数据文件。
可以在here找到一个如何执行此操作的示例。
答案 5 :(得分:1)
我在测试中使用了 PostgreSQL 的 container 实例。 https://www.testcontainers.org/#about https://www.testcontainers.org/modules/databases/jdbc/
依赖:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.15.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.15.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>1.15.3</version>
<scope>test</scope>
</dependency>
并进行测试:
@SpringBootTest
@ActiveProfiles({"test"})
@Testcontainers
class ApplicationTest {
@Container
static PostgreSQLContainer<?> postgreSQL = new PostgreSQLContainer<>("postgres:12.7");
@DynamicPropertySource
static void postgreSQLProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.username", postgreSQL::getUsername);
registry.add("spring.datasource.password", postgreSQL::getPassword);
}
@Test
void someTests() {
}
在 application-test.yml 中:
source:
datasource:
url: jdbc:tc:postgresql:12.7:///databasename