Setup und Abbau komplexer Datenbankstatus mit Hibernate / Spring / JUnit

8

Ich habe eine Klasse, die ich Unit-Testing, die ziemlich umfangreiche Datenbank-Setup erfordert, bevor die einzelnen Testmethoden ausgeführt werden können. Dieses Setup dauert sehr lange: Aus Gründen, die hoffentlich für die vorliegende Frage nicht relevant sind, muss ich die Datenbank programmatisch statt aus einem SQL-Dump auffüllen.

Das Problem, das ich habe, ist mit dem Abbau. Wie kann ich einfach alle Änderungen rückgängig machen, die in der db-Setup-Phase vorgenommen wurden?

Ich verwende derzeit Hibernate + Spring Transactional Testing, sodass meine individuellen Testmethoden in Transaktionen eingebettet sind.

Eine Lösung wäre, das db-Setup innerhalb jeder Testmethode zu machen, so dass das db-Setup automatisch zurückgesetzt wird. Die Testmethoden würden jedoch ewig dauern, da jede Methode die Datenbank neu vorbereiten müsste.

Irgendwelche anderen Ideen? Im Grunde bin ich auf der Suche nach einem Weg, um meine db-Setup zu starten, führen Sie meine einzelnen Tests (jeweils in eine Transaktion verpackt, die nach der Ausführung zurückgesetzt wird), und dann Rollback der ursprünglichen db-Setup. Irgendwelche Ideen, um das in einer Hibernate / Spring / Junit Mode zu machen? Gibt es einen Hibernate-Befehl "Alle Tabellen löschen"?

    
Brian Ferris 05.05.2009, 01:01
quelle

8 Antworten

7

Sind Sie mit einem bestimmten Datenbankanbieter festgefahren? Wenn nicht, können Sie eine In-Memory-Datenbank verwenden, z. B. HSQLDB . Wenn Sie mit den Tests fertig sind, werfen Sie einfach den Zustand weg. Dies ist nur dann sinnvoll, wenn die Tabellen zu Beginn der Testsuite (vor dem programmatischen Setup) leer sein können.

Sie müssen immer noch Tabellen erstellen, aber wenn alles über Hibernate korrekt zugeordnet wurde, können Sie mit hbm2ddl Ihre Tabellen generieren. Sie müssen Ihrer test Sitzungsfactordefinition Folgendes hinzufügen:

%Vor%

Wenn diese Lösung anwendbar erscheint, kann ich sie näher ausführen.

    
waxwing 05.05.2009, 07:24
quelle
0

Sie können sich die Annotation @AfterClass für Junit 4 ansehen. Diese Annotation wird ausgeführt, wenn die Tests abgeschlossen sind.

Ссылка

    
James Black 05.05.2009 01:52
quelle
0

DNUnit sollte Ihnen dabei helfen. Sie können separate Datensätze für jeden einzelnen Testfall erstellen, wenn Sie möchten.

    
Andrew Goldfinch 05.05.2009 01:52
quelle
0

DBUnit wird dabei sehr helfen. Sie könnten theoretisch Autocommits auf JDBC deaktivieren, aber es wird haarig. Die naheliegendste Lösung ist, DBUnit zu verwenden, um Ihre Daten in einem bekannten Status festzulegen, bevor Sie die Tests ausführen. Wenn Sie aus irgendeinem Grund Ihre Daten nach dem Ausführen der Tests wieder benötigen, können Sie @AfterClass in einer Suite anzeigen, die alle Ihre Tests ausführt. Es wird jedoch allgemein als eine bessere Vorgehensweise angesehen, Ihre Tests einzurichten und dann auszuführen Wenn der Test fehlschlägt, liegt es nicht nur daran, dass es keine Prestine-Umgebung aufgrund eines Fehlers beim Bereinigen eines anderen Tests gab. Sie stellen sicher, dass jeder Test seine Umgebung direkt aufruft.

    
Yishai 05.05.2009 02:25
quelle
0

Eine Lösung, die Sie in Betracht ziehen sollten, ist eine "manuelle" Rollback- oder Kompensationstransaktion in der DB-Zerlegung. Ich nehme an (und wenn es nicht so ist, sollte es ein triviales Add-on zu Ihren Hibernate-Entitäten sein), haben alle Ihre Entitäten das Attribut datetime create, das angibt, wann sie in die Tabelle eingefügt wurden. Ihre Db-Setup-Methode sollte Zeit vor allem anderen aufnehmen. Dann haben Sie eine ziemlich einfache Prozedur für den DB-Abbau, um alle Entitäten zu löschen, die nach der Zeit erstellt wurden, die in db setup aufgezeichnet wurde.

Natürlich funktioniert das nicht für Updates in db setup ... Aber wenn Sie eine begrenzte Anzahl von Updates haben, dann sollten Sie unberührte Bild für diese Art von Daten speichern und wiederherstellen Sie es während DB-Abbau.

    
topchef 05.05.2009 03:17
quelle
0

Wenn Sie mit einer relativ kleinen Datenbank und mit einem DBMS arbeiten, das Backups / Exporte relativ schnell durchführen kann (wie MS SQL Server), können Sie vor den Tests eine Datenbanksicherung erstellen und diese dann wiederherstellen Alle Tests sind abgeschlossen. Auf diese Weise können Sie eine Entwicklungs- / Testdatenbank einrichten und sie als Startzustand für alle Ihre Tests verwenden.

Ich habe es mit nativem JDBC gemacht, habe '' backup database '' und '' restore database '' T-SQL zwischen den Tests ausgeführt und es funktionierte ziemlich gut.

Dieser Ansatz hängt jedoch davon ab, ob Sie den DBMS-Server auf Ihrem lokalen Rechner haben (bei angemessener Geschwindigkeit), ausreichende Berechtigungen haben (was kein Problem darstellen sollte) und die Gesamtgröße der Datenbank nicht mehr als ein paar Dutzend überschreitet MB - zumindest nach meiner Erfahrung.

    
javashlook 05.05.2009 07:32
quelle
0

Gibt es einen Grund, dass Sie eine Verbindung zur Datenbank haben müssen, um Ihre Komponententests auszuführen? Es scheint, dass es einfacher ist, die Klasse neu zu strukturieren, damit Sie sich über die Interaktion mit der Datenbank lustig machen können. Sie können Klassen (mit einigen Ausnahmen) sowie Schnittstellen mit EasyMock (www.easymock.org) vortäuschen.

Wenn Ihre Klasse auf einen komplexen, bereits vorhandenen Zustand in einer verbundenen Datenbank angewiesen ist, wäre es wahrscheinlich einfacher, schnellere Tests mit Mocks zu schreiben. Wir wissen nicht, wie groß Ihr Projekt ist oder wie oft Ihre Tests ausgeführt werden, aber die Ausführungszeit kann etwas Besonderes sein, besonders in einem großen Projekt.

    
Paul Morie 08.05.2009 04:37
quelle
0

Hibernate hat eine nette kleine Eigenschaft, die stark unterdokumentiert und unbekannt ist. Sie können ein SQL-Skript während der Erstellung der SessionFactory direkt nach der Generierung des Datenbankschemas ausführen, um Daten in einer neuen Datenbank zu importieren. Sie müssen lediglich eine Datei mit dem Namen import.sql in Ihrem Klassenpfadstamm hinzufügen und entweder create oder create-drop als Ihre Eigenschaft hibernate.hbm2ddl.auto festlegen.

Ссылка

    
Oded Peer 03.11.2010 13:50
quelle

Tags und Links