web-dev-qa-db-de.com

Eingebettetes PostgreSQL für Java JUnit-Tests

Gibt es ein eingebettetes PostgreSql, damit wir unsere PostgreSql-gesteuerte Anwendung testen können?

Da PostgreSql einige Dialekte hat, ist es besser, eingebettetes PostgreSql selbst zu verwenden als andere eingebettete Datenbanken.

Eingebettet bedeutet nicht unbedingt, dass es in den JVM-Prozess eingebettet werden muss. Es muss auch nicht unbedingt die speicherinterne Persistenz verwendet werden. Es sollte automatisch vom Abhängigkeitsmanagement (Maven, Gradle) geladen werden, damit Unit-Tests auf jedem Computer ausgeführt werden können, ohne dass ein lokaler PostgreSQL-Server installiert und konfiguriert werden muss.

39
blue123

Nein, es gibt kein eingebettetes PostgreSQL im Sinne einer in den Prozess ladbaren Datenbank als Bibliothek. PostgreSQL ist prozessorientiert; Jedes Backend verfügt über einen Thread, und es werden mehrere Prozesse für die Arbeit erzeugt. Als Bibliothek macht es keinen Sinn.

Die H2-Datenbank unterstützt eine begrenzte Teilmenge des PostgreSQL-SQL-Dialekts und die Verwendung des PgJDBC-Treibers.

Was Sie tun können ist initdb eine neue temporäre Datenbank , starten Sie es mit pg_ctl auf einem zufälligen Port, damit es nicht zu Konflikten mit anderen Instanzen kommt, führen Sie Ihre Tests aus und verwenden Sie dann pg_ctl, um es zu stoppen und die temporäre Datenbank endgültig zu löschen.

Ich empfehle dringend , dass Sie die temporären Postgres auf einem nicht standardmäßigen Port ausführen. ), so dass Sie nicht riskieren, mit einem lokal installierten PostgreSQL auf dem Rechner zu kollidieren, auf dem die Tests ausgeführt werden.

(Es gibt einen "eingebetteten PostgreSQL-Client im Sinne von ecpg , im Wesentlichen einen PostgreSQL-Client eingebettet in C Quellcode als Präprozessor-basierte C-Spracherweiterung, benötigt immer noch einen laufenden Server und ist etwas unangenehm zu benutzen, nicht wirklich zu empfehlen. Es existiert hauptsächlich, um die Portierung von verschiedenen anderen Datenbanken zu vereinfachen.)

34
Craig Ringer

Dies ist ein "eingebetteter" PostgresSQL-Server, der für Unit-Tests mit Java entwickelt wurde:

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

Eingebettetes postgresql bietet eine plattformneutrale Möglichkeit zum Ausführen von postgres-Binärdateien in Komponententests . Ein Großteil des Codes wurde aus Flapdoodle OSSs Einbettungsprozess erstellt

Nebenbei gibt es auch ähnliche Projekte für Mongo , Redis , Memcached und nodejs .

46
btiernay

Ich habe das von @btiernay (yandex-qatools) vorgeschlagene Projekt ausprobiert. Ich habe ein paar Tage damit verbracht und ohne Beleidigung ist es eine überarbeitete Lösung, die in meinem Fall nicht funktioniert, da ich die Binärdateien aus dem internen Repository herunterladen wollte, anstatt ins öffentliche Internet zu gehen. Theoretisch unterstützt es das, aber in Wirklichkeit nicht.

OpenTable Embedded PostgreSQL-Komponente

Am Ende habe ich otj-pg-embedded verwendet und es funktioniert wie ein Zauber. Es wurde in Kommentaren erwähnt, also dachte ich, ich werde es auch hier erwähnen.

Ich habe es als eigenständige Datenbank und nicht als Regel für Unit-Tests und lokale Entwicklung verwendet.

Abhängigkeit:

<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

Wenn Sie eine In-Process-Version von postgres aus einer Integrationstestsuite (oder einer ähnlichen) ausführen möchten, hat in postgresql eingebettet für mich problemlos funktioniert.

Ich habe ein kleines Maven-Plugin geschrieben, das als Maven-Wrapper für eine gespaltene Version von postgresql-embedded verwendet werden kann.

3
aramcodez

Sie können eine Container -Instanz von PostgreSQL verwenden.

Da das Drehen eines Containers nur wenige Sekunden dauert, sollte dies für Unittests ausreichen. Darüber hinaus, falls Sie die Daten beibehalten müssen, z. Für die Untersuchung müssen Sie nicht den gesamten Container speichern, sondern nur die Datendateien, die außerhalb des Containers zugeordnet werden können.

Ein Beispiel dafür ist hier .

3
Arik