嵌入式PostgreSQL for Java JUnit测试

wkftcu5l  于 2023-10-20  发布在  PostgreSQL
关注(0)|答案(6)|浏览(189)

是否有一个嵌入式PostgreSQL,以便我们可以单元测试我们的PostgreSQL驱动的应用程序?
由于PostgreSQL有一些方言,因此使用嵌入式PostgreSQL本身比使用其他嵌入式数据库更好。
嵌入式并不一定意味着它必须嵌入到JVM进程中。它也不一定需要使用内存持久性。它应该由依赖管理(Maven,Gradle)自动加载,这样单元测试就可以在每台机器上运行,而无需安装和配置本地PostgreSQL服务器。

nle07wnf

nle07wnf1#

有一个“嵌入式”PostgreSQL服务器,它是为Java的单元测试而设计的:
https://github.com/yandex-qatools/postgresql-embedded
嵌入式postgresql将提供一个平台中立的方式来在单元测试中运行postgres二进制文件。大部分代码都是从Flapdoodle OSS's embed process精心制作的。
另外,还有类似的MongoRedisMemcachednodejs项目。

waxmsbnn

waxmsbnn2#

不,没有嵌入式PostgreSQL,从进程内数据库即库的意义上说。PostgreSQL是面向过程的;每个后端都有一个线程,它产生多个进程来工作。作为一个图书馆是没有意义的。
The H2 database支持PostgreSQL SQL方言的有限子集和PgJDBC驱动程序的使用。
你可以做的是initdb a new temporary database,在一个随机端口上用pg_ctl启动它,这样它就不会与其他示例冲突,运行你的测试,然后使用pg_ctl停止它,最后删除临时数据库。
我 * 强烈建议 * 在非默认端口 * 上运行临时postgres *,这样就不会有与运行测试的机器上任何本地安装的PostgreSQL冲突的风险。
(在ecpg的意义上有 *“嵌入式PostgreSQL,本质上是一个嵌入在C * 源代码 * 中的PostgreSQL * 客户端 *,作为基于预处理器的C语言扩展。它仍然需要一个运行的服务器,使用起来有点麻烦,不推荐使用。它的存在主要是为了使从各种其他数据库的移植更容易。

2nc8po8w

2nc8po8w3#

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

OpenTable嵌入式PostgreSQL组件

我最终使用了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
}
gc0ot86w

gc0ot86w4#

您可以使用PostgreSQL的container示例。
由于旋转一个容器只需几秒钟,这对于单元测试来说应该足够了。此外,如果您需要持久化数据,例如对于调查,您不需要保存整个容器,只需要保存数据文件,这些文件可以Map到容器之外。
其中一个例子是如何做到这一点可以找到here

n1bvdmb6

n1bvdmb65#

我在测试中使用了PostgreSQL的container示例。https://www.testcontainers.org/#about
相关性:

<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
1tu0hz3e

1tu0hz3e6#

如果你想从一个集成(或类似的)测试套件中运行一个进程内版本的postgres,postgresql-embedded对我来说很好。
我写了一个small maven plugin,它可以用作postgresql-embedded分叉版本的maven Package 器。

相关问题