Warum muss jUnit's fixtureSetup statisch sein?
Markierte ich eine Methode mit jUnit @BeforeClass annotation, und bekam diese Ausnahme sagen, es muss statisch sein. Was ist die Logik? Dies zwingt alle meine init auf statische Felder, die für keinen guten Grund gibt, soweit ich sehe.
In .Net (NUnit), dies ist nicht der Fall.
Bearbeiten - die Tatsache, dass eine Methode annotiert mit @BeforeClass läuft erst einmal gar nichts zu tun hat, dass es eine statische Methode - man kann eine nicht-statische Methode nur einmal ausgeführt werden (wie in NUnit).
InformationsquelleAutor der Frage ripper234 | 2009-06-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
JUnit immer erstellt eine Instanz der test-Klasse für jeder @Test-Methode. Dies ist eine grundlegende design-Entscheidung um es einfacher zu machen, tests schreiben, ohne Nebenwirkungen. Gute tests haben keine Reihenfolge-Abhängigkeiten führen (siehe F. I. R. S. T) und das erstellen von neuen Instanzen der test-Klasse und Ihre Instanz-Variablen für jeden test ist von entscheidender Bedeutung bei der Erreichung dieses. Einige testing-frameworks die Wiederverwendung der gleichen Prüfung der Klasse-Instanz für alle tests, die führt zu mehr Möglichkeiten, versehentlich erstellen von Nebenwirkungen zwischen den tests.
Und weil jede test-Methode hat seinen eigenen Beispiel, dass es keinen Sinn macht für die @BeforeClass/@AfterClass-Methoden Instanz-Methoden. Ansonsten, auf welche der test-Klasse Instanzen sollten die Methoden aufgerufen werden? Wenn es möglich wäre, für die @BeforeClass/@AfterClass-Methoden zur Referenz der Instanz-Variablen dann nur einer der @Test-Methoden haben Zugriff auf die gleichen Instanz-Variablen - den rest hätte die Instanz-Variablen auf Ihre default - Werte- und der @Test Methode wäre, die zufällig ausgewählt werden, da die Reihenfolge der Methoden in der .Klasse Datei ist nicht spezifiziert/compiler-abhängig (wenn ich mich Recht erinnere, der Java-reflection-API gibt die Methoden in der gleichen Reihenfolge wie Sie deklariert werden .Klasse Datei, obwohl auch dieses Verhalten ist nicht angegeben - ich habe geschrieben eine Bibliothek für die Sortierung, die Ihnen durch Ihre Zeilennummern).
Also die Durchsetzung dieser Methoden statisch ist die einzige vernünftige Lösung.
Hier ist ein Beispiel:
Ausgegeben:
Wie Sie sehen können, jeder der die tests ausgeführt wird, mit seiner eigenen Instanz. Was JUnit tut, ist im Grunde das gleiche wie diese:
InformationsquelleAutor der Antwort Esko Luontola
Die kurze Antwort lautet: es gibt keinen guten Grund für es zu statisch sein.
In der Tat, so dass es statische verursacht alle möglichen Probleme, wenn Sie mit Junit ausführen DBUnit basiert DAO-integration-tests. Die statische Anforderung mischt sich mit dependency injection, application-context-Zugang, Ressourcen-handling, logging, und alles, was davon abhängt, "getClass".
InformationsquelleAutor der Antwort HDave
JUnit-Dokumentation scheint selten zu finden, aber ich Schätze: vielleicht JUnit erstellt eine neue Instanz der Testklasse vor dem ausführen jedes Testfalls, also nur so für deine "Halterung" Zustand zu bleiben in läuft, ist es statisch, das kann erzwungen werden, indem Sie sicher Ihre fixtureSetup (@BeforeClass Methode) ist statisch.
InformationsquelleAutor der Antwort Blair Conrad
gibt es zwei Arten von Anmerkungen:
also @BeforeClass muss als static deklariert, weil es einmal aufgerufen wird. Auch sollten Sie Bedenken, dass Sie statisch ist der einzige Weg, um sicherzustellen, dass ordnungsgemäße "Zustand" propagation zwischen den tests (JUnit-Modell erzwingt eine test-Instanz pro @Test) und, da in Java nur statischen Methoden Zugriff auf statische Daten... @BeforeClass und @AfterClass kann nur angewendet werden, um statische Methoden.
Dieser Beispiel-test sollte klären, @BeforeClass vs @Vor Verwendung:
Ausgabe:
InformationsquelleAutor der Antwort dfa
Scheint es, dass JUnit erstellt eine neue Instanz der Testklasse für jeden test-Methode. Probieren Sie diesen code aus
Die Ausgabe ist
0
0
0
Dies bedeutet, dass, wenn die @BeforeClass Methode ist nicht static, dann wird es haben, um ausgeführt zu werden vor jeder test-Methode und würde es keine Möglichkeit zu unterscheiden zwischen der Semantik der @Before und @BeforeClass
InformationsquelleAutor der Antwort randomuser
Obwohl dies nicht Antwort auf die ursprüngliche Frage. Es wird Antworten auf die offensichtliche follow-up. Wie Sie eine Regel erstellen, dass funktioniert, bevor und nachdem Sie eine Klasse und vor und nach einem test.
Erreichen, dass Sie können verwenden Sie diese Muster:
Bevor(Klasse) die JPAConnection schafft die Verbindung einmal nach(Klasse) wird es geschlossen.
getEntityManger
gibt eine innere KlasseJPAConnection
implementiert jpa ist der EntityManager und die Verbindung innerhalb derjpaConnection
. Auf vor (test -) es beginnt eine Transaktion nach (test) rollt es wieder zurück.Dies ist nicht thread-sicher, aber gemacht werden kann, es zu sein.
Ausgewählten code der
JPAConnection.class
InformationsquelleAutor der Antwort mpkorstanje
Als pro JUnit-5, es scheint die Philosophie auf rein erstellen einer neuen Instanz pro test-Methode wurde etwas gelockert. Sie haben eine Anmerkungdass die Instantiierung einer Testklasse nur einmal. Diese Anmerkung deshalb auch erlaubt, Methoden, annotiert mit @BeforeAll/@AfterAll (Ersatz für @BeforeClass/@AfterClass) zu sein, nicht statisch. So, eine test-Klasse wie folgt aus:
drucken würde:
So, kann man eigentlich Objekte instanziieren einmal pro test-Klasse. Natürlich, dies macht es in Ihrer eigenen Verantwortung zu vermeiden mutierend Objekte instanziiert werden auf diese Weise.
InformationsquelleAutor der Antwort EJJ
Dieses Problem zu beheben, ändern Sie einfach die Methode
zu
und allen, die in dieser Methode
static
.InformationsquelleAutor der Antwort sri