嵌入式PostgreSQL for Java JUnit测试

问题描述 投票:38回答:5

是否有嵌入式PostgreSql,以便我们可以对PostgreSql驱动的应用程序进行单元测试?

由于PostgreSql有一些方言,因此最好使用嵌入式PostgreSql本身而不是其他嵌入式数据库。

嵌入式并不一定意味着它必须嵌入JVM进程中。它也不一定需要使用内存中持久性。它应该由依赖关系管理(Maven,Gradle)自动加载,这样Unit测试可以在每台机器上运行,而无需安装和配置本地PostgreSQL服务器。

postgresql maven junit embedded-database database-driven
5个回答
34
投票

不,没有嵌入式PostgreSQL,就像进程内可加载的数据库作为库而言。 PostgreSQL是面向流程的;每个后端都有一个线程,它会生成多个进程来完成工作。它作为一个图书馆并没有意义。

The H2 database支持a limited subset of the PostgreSQL SQL dialect和使用PgJDBC驱动程序。

您可以做的是initdb a new temporary database,在随机端口上使用pg_ctl启动它,这样它就不会与其他实例冲突,运行测试,然后使用pg_ctl来阻止它,最后删除临时数据库。

我强烈建议您在非默认端口上运行临时postgres,这样就不会冒险在运行测试的计算机上与任何本地安装的PostgreSQL发生冲突。

(有ecpg意义上的嵌入式PostgreSQL,本质上是一个嵌入在C源代码中的PostgreSQL客户端,作为基于预处理器的C语言扩展。它仍然需要一个正在运行的服务器,它使用起来有点讨厌,不是真的推荐。它主要存在于从其他各种数据库中轻松移植。)


46
投票

这是一个“嵌入式”PostgresQL服务器,专为从Java进行单元测试而设计:

https://github.com/yandex-qatools/postgresql-embedded

嵌入式postgresql将提供一种在平台测试中运行postgres二进制文件的平台中立方式。大部分代码都是由Flapdoodle OSS's embed process制作的

另外,MongoRedisMemcachednodejs也有类似的项目。


20
投票

我尝试了@btiernay(yandex-qatools)建议的项目。我花了好几天的时间,没有任何冒犯,它是过度设计的解决方案,在我的情况下不起作用,因为我想从内部存储库下载二进制文件而不是去公共互联网。理论上它支持它,但实际上它不支持它。

OpenTable Embedded PostgreSQL Component

我最终使用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
投票

如果你想从Integration(或类似的)测试套件中运行postgres的进程版本,postgresql-embedded对我来说很好。

我写了一个small maven plugin,它可以用作postgresql-embedded的分叉版本的maven包装器。


3
投票

您可以使用PostgreSQL的container实例。 由于旋转容器只需几秒钟,因此对单元测试而言应该足够好。此外,如果您需要保留数据,例如为了调查,您不需要保存整个容器,只需保存可以映射到容器外部的数据文件。 如何做到这一点的一个例子可以找到here

© www.soinside.com 2019 - 2024. All rights reserved.