Setup und abreißen von Komplexen Datenbank-Zustand Mit Hibernate / Spring / JUnit
Habe ich eine Klasse, die ich bin-unit-Tests erfordert relativ umfangreiche Datenbank, setup, bevor die einzelnen test-Methoden ausgeführt werden können. Das setup dauert eine lange Zeit: aus Gründen hoffentlich nicht relevant für die Frage auf der hand, ich brauche zum Auffüllen der DB programmgesteuert statt aus einem SQL-dump.
Habe ich ein Problem mit der tear-down. Wie kann ich leicht rollback alle änderungen in der db-setup-phase?
Ich bin derzeit mit Hibernate + Spring Transaktions-Testing-Unterstützung, so dass meine einzelnen test-Methoden sind verpackt in Transaktionen.
Eine Lösung wäre die db-setup innerhalb jeder test-Methode, so dass die db-setup zurückgesetzt werden würde, automatisch. Jedoch, die test-Methoden würde ewig dauern, bis da laufen jede Methode würde müssen zu re-prep der Datenbank.
Irgendwelche anderen Ideen? Im Grunde bin ich auf der Suche nach einem Weg, um mein db-setup, führen Sie meine einzelnen tests (jeweils verpackt in einer Transaktion, die bekommt Rollback nach Ausführung), und dann roll-back " - die erste db-setup. Irgendwelche Ideen auf, macht diese Arbeit in einer Hibernate /Spring /Junit-Mode? Gibt es einen Ruhezustand "drop all tables" entsprechende Befehl?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind Sie stecken mit einer bestimmten Datenbank-Anbieter? Wenn nicht, können Sie verwenden eine in-memory-Datenbank, wie HSQLDB. Wenn Sie fertig sind mit den tests, die Sie einfach wegwerfen, den Staat. Dies ist nur dann geeignet, wenn die Tabellen auch leer sein kann am Anfang der test-suite (bevor Ihr Programmatischer setup, das ist).
Brauchen Sie noch, um Tabellen zu erstellen, aber wenn alles ordentlich gemappt mit Hibernate können Sie den hbm2ddl zu erstellen Sie Ihre Tabellen. Alles, was Sie tun müssen ist, fügen Sie Folgendes zu Ihrer test session factory definition:
Wenn diese Lösung scheint zutreffend kann ich weiter drauf ein.
Möchten Sie vielleicht zu schauen, @AfterClass-Anmerkung für Junit 4. Diese Anmerkung wird ausgeführt, wenn die tests fertig sind.
http://cwiki.apache.org/DIRxDEV/junit4-primer.html
DNUnit sollten Sie in dieser Hinsicht helfen.
Können Sie erstellen separate Datensätze für jeden einzelnen Testfall, wenn Sie es wünschen.
DBUnit wird eine Menge helfen, mit diesem. Theoretisch könnten Sie ausschalten autocommits auf JDBC -, aber es wird haarig. Die naheliegendste Lösung ist die Verwendung von DBUnit, um Ihre Daten in einem bekannten Zustand vor dem ausführen der tests. WENN aus irgendeinem Grund müssen Sie Ihre Daten zurück, nachdem die tests ausgeführt werden, kann man sich bei @AfterClass auf eine suite läuft, dass Sie alle Ihre tests, aber es wird allgemein als eine bessere Praxis, um Ihre tests und führen Sie Sie, so dass, wenn der test fehlschlägt, ist es nicht nur, weil Sie nicht über eine perfekte Umgebung durch, um einen Fehler zu bereinigen, einen anderen test. Stellen Sie sicher, dass jeder test legt seine Umwelt direkt.
One-Lösung, die Sie betrachten wünschen können, ist, eine "manuelle" rollback oder kompensierende Transaktion in der db reißen. Ich nehme an (und wenn nicht, dann sollte es eine triviale add-on für Ihre Hibernate-Entitäten) alle Ihre Einheiten haben datetime-Attribut erstellen, der anzeigt, Wann Sie in die Tabelle Eingefügt wurden. Ihre db-setup-Methode sollte Rekordzeit vor alles andere. Dann haben Sie eher einfaches Verfahren für die db abreißen zu löschen alle Elemente, die erstellt wurden, nach Zeit recored in db-setup.
Natürlich, dies funktioniert nicht für updates in db setup... Aber wenn Sie haben begrenzte Anzahl von updates, dann sparen Sie unberührte Bild für diese Art von Daten und es wieder bei db reißen.
Arbeitet man mit relativ kleinen Datenbank, und mit einem DBMS, die das tun können backups/Export relativ schnell (wie MS SQL-Server), können Sie erstellen Sie ein backup der Datenbank, bevor die tests, und dann wiederherstellen, wenn alle Tests abgeschlossen sind. Dies ermöglicht Ihnen das einrichten einer Entwicklungs - /Test-Datenbank und verwenden Sie es als Start-Status für alle tests.
Ich habe es mit native JDBC ausführen von "Datenbank sichern" und "Datenbank wiederherstellen" T-SQL in-zwischen den tests, und es klappte auch einigermaßen.
Dieser Ansatz ist jedoch abhängig von der DBMS-server auf dem lokalen Rechner (bei angemessener Geschwindigkeit), dass Sie über ausreichende Berechtigungen (was als kein problem sein sollte), und die Gesamtgröße der Datenbank nicht mehr als ein paar Dutzend MB - zumindest in meiner Erfahrung.
Gibt es einen Grund, dass Sie haben, um eine Verbindung zur Datenbank, zum ausführen von unit-tests? Es klingt wie könnte es leichter sein, Sie zu überarbeiten Sie Ihre Klasse, so dass Sie verhöhnen die Interaktion mit der Datenbank. Sie können die mock-Klassen (mit einigen Ausnahmen) sowie Schnittstellen mit EasyMock (www.easymock.org).
Wenn Ihre Klasse stützt sich auf eine komplexe pre-bestehenden Zustand in einer angeschlossenen Datenbank, es wäre wahrscheinlich einfacher zu schreiben, schnellere Ausführung von tests unter Verwendung von mocks. Wir wissen nicht, wie groß Ihr Projekt ist oder wie oft Sie Ihre tests ausgeführt werden, aber die Ausführung könnte Zeit sein, etwas zu denken, vor allem in einem großen Projekt.
Hibernate hat eine nette kleine Funktion, die stark unter-dokumentiert und unbekannt. Führen Sie ein SQL-Skript während der SessionFactory creation direkt nach dem Datenbank-schema-generation zum importieren von Daten in eine frische Datenbank. Sie müssen nur fügen Sie eine Datei namens import.sql in der classpath-root und entweder zu erstellen oder erstellen-drop in Ihren Ruhezustand.hbm2ddl.auto-Eigenschaft.
http://in.relation.to/Bloggers/RotterdamJBugAndHibernatesImportsql