Matti Mäkitalo: Frage zu Triggern in SQL

Beitrag lesen

Hallo,

Unit Tests macht man doch möglichst gegen einen Mock der Datenbank, gelle? Weswegen man die SQLs in eine eigene Schicht auslagert

Ja: wenn man eine Funktion testen will, die SQL ausführt, dann braucht man eine Datenbank - meist nimmt man dazu eine In-Memory-Datenbank (z.B. H2, sqlite oder ein "richtiges" DBMS, welches nicht persistiert).

Hat dieses SQL Nebeneffekte (z.B. durch Trigger) dann muss die Datenbank alle Tabellen und Trigger umfassen, die betroffen sein könnten.

Hier wird es dann schwer: wenn ich in einem "normalen" (nicht-Datenbank) Unit-Test eine Dependency weglasse werde ich meinen Code im Besten Fall gar nicht kompilieren können. Wenn ich einen Trigger weglasse dann läuft alles durch, und ich muss durch Assertions klarmachen, dass meine Trigger-Aktion so ausgeführt wurde wie gewünscht. Und wenn man es ganz richtig machen will muss man auch testen, dass ungewünschte Aktionen (z.B. Update von Schwesterzeilen, weil ein WHERE vergessen wurde) nicht ausgeführt wurde - und zwar auf der gesamten Datenbank. D.h. man ist schnell an einem Punkt, an dem man eigentlich einen kompletten Datenbank-Inhalt initialisiert, dann das eine SQL-Kommando absetzt, und dann die komplette Datenbank prüft, ob alle gewünschten Aktionen durchgeführt wurden und nichts anderes getan wurde.

Oder man fängt an, an unbeteiligte Tabellen Trigger zu hängen die abstürzen (um Mißerfolg klarzumachen, sowas wie Assertions.fail() oder assertTrue(false)).

Wie gesagt: in einem normalen Unit-Test mit Dependency-Injection ist sowas einfach: eine Unit, die nicht injected wird, kann nicht aufgerufen werden. Und die ein/zwei Methoden einer Unit, die man injected, aber wo man die speziellen Methoden nicht braucht (kleine Warnlampe btw) muss man dann halt passend verifyen/mocken.

Lange Rede, kurzer Sinn:

  • Unit-Test von SQL-Queries (z.B. Repositories) ist möglich und sinnvoll.
  • Diese Tests sind aber schwerer zu schreiben und zu warten und brauchen auch länger (was man aber erst merkt, wenn man davon mal 100 geschrieben hat - dann sind die Unit-Tests auf einmal nichtmehr in 5sec durchgelaufen sondern in 1min, was die DevExp wesentlich stört).

Viele Grüße Matti