web-dev-qa-db-fra.com

PostgreSQL intégré pour Java tests JUnit

Existe-t-il un PostgreSql intégré pour que nous puissions tester nos applications pilotées par PostgreSql?

Étant donné que PostgreSql possède certains dialectes, il est préférable d'utiliser PostgreSql intégré lui-même que d'autres bases de données intégrées.

Embarqué ne signifie pas nécessairement qu'il doit être intégré au processus JVM. Il n'a pas non plus nécessairement besoin d'utiliser la persistance en mémoire. Il doit être chargé automatiquement par la gestion des dépendances (Maven, Gradle), afin que les tests unitaires puissent s'exécuter sur chaque machine sans avoir à installer et configurer un serveur PostgreSQL local.

39
blue123

Non, il n'y a pas de PostgreSQL intégré, dans le sens d'une base de données chargeable en cours de processus en tant que bibliothèque. PostgreSQL est orienté processus; chaque backend a un thread, et il engendre plusieurs processus pour effectuer le travail. Cela n'a pas de sens en tant que bibliothèque.

La base de données H2 prend en charge n sous-ensemble limité du dialecte SQL PostgreSQL et l'utilisation du pilote PgJDBC.

Ce que vous pouvez faire est initdb une nouvelle base de données temporaire , démarrez-la avec pg_ctl sur un port aléatoire afin qu'il n'entre pas en conflit avec d'autres instances, exécutez vos tests, puis utilisez pg_ctl pour l'arrêter et enfin supprimer la base de données temporaire.

Je recommande fortement d'exécuter les postgres temporaires sur un port non par défaut afin de ne pas risquer d'entrer en collision avec un PostgreSQL installé localement sur la machine exécutant les tests.

(Il y a "PostgreSQL intégré dans le sens ecpg , essentiellement un client PostgreSQL intégré au code source C en tant qu'extensions de langage C basées sur un préprocesseur. Il nécessite toujours un serveur en cours d'exécution et c'est un peu désagréable à utiliser, pas vraiment recommandé. Il existe principalement pour faciliter le portage à partir de diverses autres bases de données.)

34
Craig Ringer

Il s'agit d'un serveur PostgresSQL "intégré" qui a été conçu pour les tests unitaires à partir de Java:

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

Postgresql intégré fournira un moyen neutre de plate-forme pour exécuter le binaire postgres dans les tests unitaires . Une grande partie du code a été conçue à partir de processus d'intégration de Flapdoodle OSS

Par ailleurs, il existe également des projets similaires pour Mongo , Redis , Memcached et nodejs .

46
btiernay

J'ai essayé le projet proposé par @btiernay (yandex-qatools). J'ai passé quelques bons jours avec cela et sans aucune infraction, c'est une solution trop développée qui ne fonctionne pas dans mon cas car je voulais télécharger les binaires depuis le référentiel interne plutôt que d'aller sur Internet public. En théorie, il le soutient, mais en fait il ne le fait pas.

Composant OpenTable Embedded PostgreSQL

J'ai fini par utiliser otj-pg-embedded et cela fonctionne comme un charme. Il a été mentionné dans les commentaires, j'ai donc pensé le mentionner ici également.

Je l'ai utilisé en tant que base de données autonome et non via une règle pour les tests unitaires et le développement local.

Dépendance:

<dependency>
    <groupId>com.opentable.components</groupId>
    <artifactId>otj-pg-embedded</artifactId>
    <version>0.7.1</version>
</dependency>

Code:

@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
}
20
Jan Zyka

Si vous cherchez à exécuter une version in-process de postgres à partir d'une suite de tests d'intégration (ou similaire), le postgresql-embedded a bien fonctionné pour moi.

J'ai écrit un petit plugin maven qui peut être utilisé comme wrapper maven autour d'une version fourchue de postgresql-embedded.

3
aramcodez

Vous pouvez utiliser une instance container de PostgreSQL.

. De plus, au cas où vous auriez besoin de conserver les données, par ex. pour l'investigation, vous n'avez pas besoin d'enregistrer l'intégralité du conteneur, uniquement les fichiers de données, qui peuvent être mappés en dehors du conteneur.

Un exemple de la façon de procéder peut être trouvé ici .

3
Arik