In der Frühjahrsdokumentation zum Testen , es heißt:
Vermeiden Sie Fehlalarme beim Testen von ORM Code
Wenn Sie Code testen, der ein ORM-Rahmen wie JPA oder Hibernate, flush den darunterliegenden Sitzung innerhalb von Testmethoden, die Aktualisieren Sie den Status der Sitzung. Fehler beim Löschen des ORM-Frameworks Die zugrunde liegende Sitzung kann zu falschen Ergebnissen führen Positives: Ihr Test kann bestehen, aber der Derselbe Code löst in a eine Ausnahme aus leben, Produktionsumgebung. In dem folgenden Hibernate-basierten Beispieltest Fall, eine Methode zeigt ein falsches positiv und die andere Methode stellt die Ergebnisse von Die Sitzung wird gelöscht.
Kann jemand erklären, warum ich Flush callen muss?
Nun, Sie haben den interessanten Teil, das Beispiel, wirklich übersprungen :) Hier ist es:
%Vor%Was dieses Beispiel zu veranschaulichen versucht, ist, dass wenn Sie nicht wirklich die Sitzung (AKA den Cache der ersten Ebene) zum Synchronisieren der In-Memory-Daten mit der Datenbank synchronisieren, Sie nicht wirklich die Datenbankintegration testen und möglicherweise nicht testen echtes erwartetes Verhalten oder ein Problem zu verfehlen.
Zum Beispiel könnte die Datenbank einen Fehler zurückgeben, zum Beispiel aufgrund eines Constraint-Verstoßes, und wenn Sie die Datenbank nicht treffen, werden Sie dieses richtige Verhalten nicht zeigen, wie in der obigen flush
Test-Methode. Diese Testmethode sollte fehlschlagen oder eine Ausnahme erwarten, aber sie wird bestehen. Auf der anderen Seite testet die andere Testmethode mit dem Flush das reale Verhalten. Daher muss falsePositive()
.
Die Frühjahrsdokumentation verwendet das falsche Konzept. Es war klar,
aber derselbe Code löst in einer Live-Produktionsumgebung eine Ausnahme aus
Hier geht wikipedia
Fehler vom Typ II, auch bekannt als "Fehler der zweiten Art", ein β-Fehler, oder ein "falsch-negatives" : der Fehler, eine Nullhypothese nicht zu verwerfen, wenn sie sich befindet Tatsache nicht wahr. Ein Beispiel dafür wäre, wenn ein Test zeigt, dass eine Frau nicht schwanger ist, obwohl sie in Wirklichkeit ist.
Wenn das Beispiel von Spring angezeigt wird, gibt die Produktionsumgebung eine Ausnahme aus (A GenericJDBCException), wurde jedoch nicht erkannt . Um zu sehen, müssen Sie das zugrunde liegende Commit aufrufen, wenn Sie einen ORM-Provider verwenden.
XUnit Testmusterdefinition
Eine Situation, in der ein Test bestanden wird, obwohl das getestete System nicht ordnungsgemäß funktioniert .
Also das richtige Konzept ist falseNegative
%Vor%Das Kommentieren von Spring-Tests mit @Transactional ist praktisch, aber es ist nicht so, wie Ihr Produktionscode ausgeführt wird. Die Annotation @Transactional startet eine Transaktion, bevor die Testmethode ausgeführt wird, und sie wird nach Abschluss der Testmethode zurückgesetzt.
Während dem Commit ein Flush vorausgeht, ist der Rollback nicht der Fall, daher ist ein manueller Flush ein Sicherheitsmechanismus, um sicherzustellen, dass alle Entity-Änderungen in SQL-Anweisungen umgesetzt werden.
Ein geeigneteres Design wäre, die Transaktionsgrenzen explizit wie folgt zu zeichnen:
%Vor%Die TransaktionTemplate wird Ihren Code festschreiben, so dass keine manuellen Leerungen erforderlich sind.
Wenn Sie @Transactional-Service-Methoden über ihre Schnittstelle aufrufen, benötigen Sie das transactionTemplate überhaupt nicht, da Sie einen Spring-Proxy aufrufen, der TransactionInterceptor aufruft (vorausgesetzt, Sie haben Spring angewiesen, Transaktionsankündigungen zu beachten) und daher Transaktionen werden in Ihrem Namen gestartet / committed.
Hat jemand die Annotation @TransactionConfiguration überprüft? Wenn Sie @Transactional Annotation in Ihrem Projekt verwenden, können Sie einfach @TransactionConfiguration (defaultRollback = false, transactionManager="YourTransactionManager") in Ihrem Testfall perfekt arbeiten, hoffentlich wird dies Ihnen helfen.
Tags und Links jpa hibernate spring testing false-positive