2010-01-06 7 views
39

Wie sieht Ihre Spring-Konfiguration für Integrationstests aus, wenn Sie embedded h2 datasource und optional JUnit verwenden?Spring-Konfiguration für die eingebettete H2-Datenbank für Tests

Mein erster Versuch mit einem SingleConnectionDataSource funktionierte grundsätzlich, aber scheiterte an komplizierteren Tests, bei denen Sie mehrere Verbindungen gleichzeitig oder ausgesetzte Transaktionen benötigen. Ich denke, h2 in tcp based server mode könnte auch funktionieren, aber dies ist wahrscheinlich nicht der schnellste Kommunikationsmodus für eine temporäre eingebettete Datenbank im Speicher.

Was sind die Möglichkeiten und ihre Vorteile/Nachteile? Wie erstellen Sie die Tabellen/befüllen Sie die Datenbank?


Update: Lassen Sie uns einige konkrete Anforderungen angeben, die für solche Tests wichtig sind.

  • Die Datenbank sollte nur vorübergehend sein und im Speicher
  • Die Verbindung sollte wahrscheinlich nicht tcp verwenden, für Geschwindigkeitsanforderungen
  • Es wäre schön, wenn ich ein Datenbank-Tool verwenden, könnte den Inhalt der Datenbank zu inspizieren während Debuggen
  • wir haben eine Datenquelle zu definieren, da wir nicht die Anwendungsserver-Datenquelle in Unit-Tests

Antwort

45

Mit dem Vorbehalt, dass ich weiß nicht, ob es irgendein Werkzeug, das die Datenbank überprüfen kann, denke ich, dass eine einfache Lösung, um den Frühling eingebettete Datenbank (3.1.x docs, current docs) zu verwenden, wäre das unterstützt HSQL, H2 und Derby .

Verwendung von H2, die XML-Konfiguration wie folgt aussehen würde:

<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 Java-basierte Konfiguration bevorzugen, können Sie ein DataSource wie folgt instanziiert (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 vom Skript db-schema.sql erstellt und mit Testdaten aus dem db-test bestückt -data.sql Skript.

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

+0

Wenn die Datenbank für die automatische DDL-Generierung von Modellen im Ruhezustand (hbm2ddl) konfiguriert wurde, werden Skripts vor der Datenstrukturgenerierung über Hibernate ausgeführt. Gibt es eine Lösung, um diese Skripte nach hbm2ddl auszuführen? –

0

ich denke, es ist am besten Ihre Produktion Datasource-Implementierung verwenden können (nur wi th verschiedene Verbindungszeichenfolge) für die Unit-Tests.

Wie auch immer "bei komplizierteren Tests fehlgeschlagen" gibt nicht genügend Informationen für eine detailliertere Antwort.

(Selbst ad: check this)

+5

Die Produktionsdatenbank für Komponententests? Wenn Sie z.B. eine Oracle-Datenbank für automatisierte Tests während z.B. Ein Maven Build kann leicht in Schwierigkeiten geraten. Das ist ziemlich langsam, hängt von den Daten ab, die da sind, und niemand sonst sollte gleichzeitig einen Build machen. 8-) Ich bevorzuge h2 im Orakelmodus. BTW: Diese Frage ist ziemlich allgemein über die verfügbaren Möglichkeiten, weniger über mein spezifisches Problem. –

+0

nein, die Produktion DataSource-Implementierung. Mit Unterschied nur in Verbindungszeichenfolge – Bozho

+0

Ah, OK, aber das wäre eine Datenquelle in einem Anwendungsserver. Das ist also nicht möglich. –

18

I sind derzeit in einer Test nur springconfig-Datei als Datenquelle:

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

erstellen/Fallenlassen der Tabellen können mit executeSqlScript erfolgen, wenn zwingende AbstractAnnotationAwareTransactionalTests.onSetUpBeforeTransaction oder mit SimpleJdbcTestUtils.executeSqlScript an einem geeigneten Ort.

Vergleichen Sie auch this posting.

+0

"Ich habe keinen Ersatz für executeSqlScript mit JUnit4 Tests gefunden" versuchen, org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests zu erweitern –

+0

Vielen Dank für diese Antwort. Meine Komponententests scheiterten mit der In mem DB, bis ich DB_CLOSE_DELAY hinzufügte –

8

H2 ist mit einer integrierten Connection Pool-Implementierung gebündelt. Die folgende XML stellt ein Beispiel für sie als Datenquelle Bohne mit ohne Notwendigkeit, zusätzliche Abhängigkeiten von DBCP oder C3P0 vorstellen:

<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 durch den Aufruf einer Methode Dispose abgeschaltet werden, wenn der Frühling Anwendungskontext geschlossen wird.