webentwicklung-frage-antwort-db.com.de

Federkonfiguration für eingebettete H2-Datenbank für Tests

Wie sieht Ihre Spring-Konfiguration für Integrationstests aus, wenn Sie eine eingebettete H2-Datenquelle und optional JUnit verwenden?

Mein erster Versuch mit einer SingleConnectionDataSource hat grundsätzlich funktioniert, ist aber bei komplizierteren Tests fehlgeschlagen, bei denen Sie mehrere Verbindungen gleichzeitig benötigen oder Transaktionen ausgesetzt haben. Ich denke, h2 in TCP-basierter Servermodus könnte auch funktionieren, aber dies ist wahrscheinlich nicht der schnellste Kommunikationsmodus für eine temporär eingebettete Datenbank im Speicher.

Was sind die Möglichkeiten und deren Vor-/Nachteile? Wie erstellen Sie die Tabellen bzw. füllen die Datenbank auf?


Update: Geben wir einige konkrete Anforderungen an, die für solche Tests wichtig sind.

  • Die Datenbank sollte temporär und im Speicher sein
  • Die Verbindung sollte aus Geschwindigkeitsgründen wahrscheinlich kein TCP verwenden
  • Es wäre schön, wenn ich ein Datenbank-Tool verwenden könnte, um den Inhalt der Datenbank während des Debuggens zu überprüfen
  • Wir müssen eine Datenquelle definieren, da wir die Anwendungsserver-Datenquelle nicht in Komponententests verwenden können
40

Mit dem Vorbehalt, dass ich nicht weiß, ob es ein Tool gibt, mit dem die Datenbank überprüft werden kann, halte ich die Verwendung der eingebetteten Spring-Datenbank für eine einfache Lösung ( .1.x docs , aktuelle Dokumente ), die HSQL, H2 und Derby unterstützen.

Mit H2 würde Ihre XML-Konfiguration folgendermaßen aussehen:

<jdbc:embedded-database id="dataSource" type="H2">
    <jdbc:script location="classpath:db-schema.sql"/>
    <jdbc:script location="classpath:db-test-data.sql"/>
</jdbc:embedded-database>

Wenn Sie eine Java basierte Konfiguration bevorzugen, können Sie ein DataSource wie folgt instanziieren (beachten Sie, dass EmbeddedDataBaseDataSource erweitert):

@Bean(destroyMethod = "shutdown")
public EmbeddedDatabase dataSource() {
    return new EmbeddedDatabaseBuilder().
            setType(EmbeddedDatabaseType.H2).
            addScript("db-schema.sql").
            addScript("db-test-data.sql").
            build();
}

Die Datenbanktabellen werden mit dem Skript db-schema.sql erstellt und mit Testdaten aus der Datenbank gefüllt -test-data.sql Skript.

Vergessen Sie nicht, den H2-Datenbanktreiber zu Ihrem Klassenpfad hinzuzufügen.

48
matsev

Ich füge derzeit in einer Nur-Test-Springconfig-Datei Folgendes als Datenquelle ein:

<bean id="database.dataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
    <constructor-arg>
        <bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
            <property name="driverClass" value="org.h2.Driver" />
            <property name="url"
                value="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=Oracle;TRACE_LEVEL_SYSTEM_OUT=2" />
        </bean>
    </constructor-arg>
</bean>

<!-- provides a H2 console to look into the db if necessary -->
<bean id="org.h2.tools.Server-WebServer" class="org.h2.tools.Server" 
    factory-method="createWebServer" depends-on="database.dataSource" 
    init-method="start" lazy-init="false">
    <constructor-arg value="-web,-webPort,11111" />
</bean>

Das Erstellen/Löschen der Tabellen kann mithilfe von executeSqlScript erfolgen, wenn AbstractAnnotationAwareTransactionalTests.onSetUpBeforeTransaction oder mit SimpleJdbcTestUtils.executeSqlScript an einer geeigneten Stelle überschrieben wird.

Vergleichen Sie auch dieses Posting .

18

H2 wird mit einer integrierten Verbindungspool-Implementierung gebündelt. Die folgende XML-Datei enthält ein Beispiel für die Verwendung als Datenquellen-Bean, ohne dass zusätzliche Abhängigkeiten von DBCP oder C3P0 eingeführt werden müssen:

<bean id="dataSource" class="org.h2.jdbcx.JdbcConnectionPool" destroy-method="dispose">
    <constructor-arg>
        <bean class="org.h2.jdbcx.JdbcDataSource">
            <property name="URL" value="jdbc:h2:dbname"/>
            <property name="user" value="user"/>
            <property name="password" value="password"/>
         </bean>
    </constructor-arg>
</bean> 

Die Datenbank wird heruntergefahren, indem eine dispose-Methode aufgerufen wird, wenn der Spring-Anwendungskontext geschlossen wird.

9
ejboy

Ich denke, es ist am besten, Ihre DataSource-Implementierung (nur mit unterschiedlicher Verbindungszeichenfolge) für die Unit-Tests zu verwenden.

Wie auch immer, "bei komplizierteren Tests gescheitert" liefert nicht genügend Informationen für eine detailliertere Antwort.

(Eigenwerbung: bitte ankreuzen )

0
Bozho