Tests schreiben um Transaktions(un)sicherheit zu prüfen

dermoritz

Bekanntes Mitglied
ich baue gerade Integrationstests für eine selbsgestrickte und "Application-managed"-DB-Schnittstelle. Nun sind Tests eigentlich nur dann tauglich wenn man auch die Fehlerscenarien durchspielen kann.

Wie kann man z.B. programatisch provozieren das Transaktionen fehlschlagen. Es geht mir darum zu überprüfen, dass die richtigen Exceptions in der richtigen Weise behandelt werden.
 

dermoritz

Bekanntes Mitglied
ich möchte ja ebend keine mocks verwenden sondern einen "echten" test machen. Also in meinem Fall will ich eine Schnittstelle zu einer MySql-DB testen.
 
M

maki

Gast
Mit DBUnit kann man eine DB recht elegant mit Testdaten befüllen lassen, dann nur noch die Fehler provozieren, oder hab ich dich falsch verstanden?
 

dermoritz

Bekanntes Mitglied
wie provoziere ich die Fehler? also wie kann ich z.B. die DB-Verbindung unterbrechen bzw. das simulieren. Ich würde gerne ein rollback()-Exception auslösen.
 
S

SlaterB

Gast
Runtime.runProcess("shutdown db");
oder wie?

auf ein System, auf welches du keinen Zugriff hast, kannst du auch keine Kontrolle ausüben,
die Alternative ist wie gesagt ein Dummy statt einer richtigen DB wo du dann gerne auch einen Abbruch simulieren kannst

vielleichst stellst du eine DB-Query mit fehlerhafter Syntax? gibt gewiss auch eine Exception,
oder einfach
> throw new XYException()
aus der DB kommt ja sicher eine Exception eines einfachen Interfaces, welches du auch erweitern kannst,
falls du nicht generell alle Arten von Exceptions abfängst
 
Zuletzt bearbeitet von einem Moderator:

dermoritz

Bekanntes Mitglied
@fastjack: genau
ich möchte wie bei anderen Unit/Integrationstests eben auch die Ausnahmesituationen Testen. das macht man ja mit: "expected=IllegalArgumentException.class". Nur wie kann ich solche Ausnahmen auf DB-Ebene auslösen. Einfach "throw new rollbackexception()" wird nicht helfen - sie würde ja erst geworfen nachdem die Anweisung davor ausgeführt wurde. Praktisch kann icih natürlich während einer Tranaktion mal das Netzkabel ziehen - damit wäre der Test aber irgendwie nicht reproduzierbar.
 
S

SlaterB

Gast
warum genau hilft 'throw new rollbackexception()' oder eine Query mit Syntax-Fehler nicht?
was hat irgendeine 'Anweisung davor' damit zu tun?
 
M

maki

Gast
Solltest dir imho mehr Gedanken um die Tests machen.

Wenn das Netzwerkkabel gezogen wird, ist es volkommen egal welche Excecption geworfen wird, deine Anwendung ist tot.
Interessant wäre doch nur, ob die DB selber einen Rolback nach Timeout macht, dafür brauchst du aber genaugenommen nicht mal eine Java App.
Es würde doch reichen, dass du prüfst ob eine laufende transaktion da ist, oder nicht.

Oder willst du etwa die DB Features testen? ;) Das wäre dann ein test der DB....
 

dermoritz

Bekanntes Mitglied
theoretisch hast du völlig recht maki, aber ich mach eine "application managed"-jpa Anwendung und da muss man sozusagen selbst an den richtigen stellen ein try-catch machen und ein Rollback anstoßen - zumindest unter bestimmten umständen. Also ich hab mich daran gehalten:
Java Notepad: How to close a JPA EntityManger in web applications

Und ich würde gerne Die Methode die diesen Code enthält Testen. und speziell eben den part
Code:
if (tx.isActive())
 tx.rollback();
hätte ich gerne im coveragetool auf grün. In dem Fall müsste man also erreichen, das die Transaktion noch aktiv ist, also nicht commited wurde. Und das kann man ja nur erreichen solange die Transaktion/Methode läuft, oder? Also während oder vor Ausführung der Methode muss man erreichen, das es während der Ausführung zu einem Fehler (IllegalStateException) kommt. - Geht das?
 
G

Gast2

Gast
Und warum provozierst du in der Transaktion nicht einfach einen Fehler? Z.B. duplicate key violation.
 

dermoritz

Bekanntes Mitglied
das ist nicht ganz so einfach, da mein code so etwas im Vorfeld abprüft (seperater Testfall). Aber der Testcode könnte ja nach dem abprüfen per Qery einen entsprechenden eintrag schreiben so dass im Moment des schreibens der Duplicate KEy Fehler kommt. Ich glaub das ist eine gute Idee fassy -- danke
 
S

SlaterB

Gast
ist das was anderes als die von mir schon angesprochenen Queries mit Syntax-Fehler/ selber Exception werfen? ;)
 

dermoritz

Bekanntes Mitglied
prnzipiell ist es nix anderes. das Problem ist die Art der Implementierung der zu testenden Klasse. Die versucht die ganzen db-Geschichten wegzuabstrahieren. Letztendlich kann ich dieser Klasse nur sagen: speichereEinträge(Liste). Das Problem ist, dass ich während des speicherns einen Fehler brauche - quasi echt parallel.
Nun hilft der Vorschlag von fassy insofern, dass die Klasse die Möglichkeit bietet zunächst die Liste zu übergeben und in einem 2. Schritt zu speichern. Falls nun die Eindeutigkeit der Schlüssel beim Liste übergeben geprüft wird und nicht beim schreiben, kann man dazwischen einfah einen Eintrag mit einem entsprechende Key machen um dann nen Fehler und ein Rollback zu bekommen.

Aber wenn ich es mir recht überlege habe ich diese "Lücke" aus der Klasse entfent - Sie überprüft in einem Rutsch die eindeutigkeit/Validität der Einträge der Liste und setzt dann eine Transaktion abm welche die Liste schreibt. Letztendlch komme ich glaube nicht um 2 synchronisierte Threads herum - der ein prfuscht rum während der andere versucht einzutragen?!
 
Ähnliche Java Themen

Ähnliche Java Themen


Oben