[JAVA] Ich habe den Lebenszyklus der Erweiterung von JUnit Jupiter untersucht

Wie ist der Lebenszyklus einer Erweiterungsinstanz, die versucht, eine Erweiterung für JUnit 5 (JUnit Jupiter) zu schreiben? Machen Sie ein Memorandum.

Umgebung

TL;TR

Überprüfung des Erweiterungsmodells

Das Erweiterungsmodell von JUnit 5 ist ein Mechanismus zum Standardisieren der Vorverarbeitung, Nachbearbeitung, Ausnahmeverarbeitung usw. für jeden Test. Der Freiheitsgrad ist niedriger als der der "Regel" von Junit 4, aber Sie können einfach eine Erweiterung erstellen, indem Sie eine Schnittstelle implementieren, die Erweiterungspunkte unterstützt.

Es gibt drei Möglichkeiten, die Erweiterung zu verwenden.

  1. Registrieren Sie die Nebenstelle bei "@ Nebenstelle".
  2. Registrieren Sie die Erweiterung programmgesteuert mit "@ RegisterExtension".
  3. Registrieren Sie sich automatisch beim Service Loader.

Verwenden Sie dieses Mal die Methoden 1 und 2, um zu überprüfen, wann die Erweiterungsinstanz erstellt wurde.

Die zur Bestätigung verwendeten Erweiterungen lauten wie folgt.

FooExtension.java


import org.junit.jupiter.api.extension.*;

public class FooExtension implements BeforeEachCallback, AfterEachCallback, BeforeAllCallback, AfterAllCallback {

    {
        System.out.println(String.format("[%s] created", this.toString()));
    }

    @Override
    public void beforeAll(ExtensionContext extensionContext) throws Exception {
        System.out.println(String.format("[%s] before all", this.toString()));
    }

    @Override
    public void beforeEach(ExtensionContext context) throws Exception {
        System.out.println(String.format("[%s] before each", this.toString()));
    }

    @Override
    public void afterEach(ExtensionContext extensionContext) throws Exception {
        System.out.println(String.format("[%s] after each", this.toString()));
    }

    @Override
    public void afterAll(ExtensionContext extensionContext) throws Exception {
        System.out.println(String.format("[%s] after all", this.toString()));
    }
}

Registrieren Sie die Erweiterung mit "@ Extension"

Quelle

@ExtendWith(FooExtension.class)
public class ExtensionTest {

    @Test
    void test1() { System.out.println("test 1"); }

    @Test
    void test2() { System.out.println("test 2"); }

    @Test
    void test3() { System.out.println("test 3"); }
}

Ergebnis

[example.FooExtension@70325e14] created
[example.FooExtension@70325e14] before all
[example.FooExtension@70325e14] before each
test 1
[example.FooExtension@70325e14] after each
[example.FooExtension@70325e14] before each
test 2
[example.FooExtension@70325e14] after each
[example.FooExtension@70325e14] before each
test 3
[example.FooExtension@70325e14] after each
[example.FooExtension@70325e14] after all

Sie können sehen, dass jeder Test eine Erweiterungsinstanz gemeinsam nutzt. Für jeden Test wird eine Instanz von ExtensionTest erstellt. Das gleiche Ergebnis wurde jedoch erzielt, wenn die ErweiterungTest-Instanz für "@TestInstance (Lifecycle.PER_CLASS)" freigegeben wurde.

@ RegisterExtension + Registererweiterung mit statischem Feld

Quelle

SecondExtensionTest.java


public class SecondExtensionTest {

    @RegisterExtension
    static FooExtension fooExtension = new FooExtension();

    @Test
    void test1() { System.out.println("test 1"); }

    @Test
    void test2() { System.out.println("test 2"); }

    @Test
    void test3() { System.out.println("test 3"); }
}

Ergebnis

[example.FooExtension@55183b20] created
[example.FooExtension@55183b20] before all
[example.FooExtension@55183b20] before each
test 1
[example.FooExtension@55183b20] after each
[example.FooExtension@55183b20] before each
test 2
[example.FooExtension@55183b20] after each
[example.FooExtension@55183b20] before each
test 3
[example.FooExtension@55183b20] after each
[example.FooExtension@55183b20] after all

Da es sich um ein statisches Feld handelt, wird natürlich dieselbe Instanz gemeinsam genutzt.

Registererweiterung mit @ RegisterExtension + nicht statischem Feld

Entfernen wir die "statische" der "fooExtension" des SecondExtensionTest.

Für Lifecycle.PER_METHOD

Quelle

SecondExtensionTest.java


public class SecondExtensionTest {

    @RegisterExtension
-   static FooExtension fooExtension = new FooExtension();
+   FooExtension fooExtension = new FooExtension();

    //Unterlassung
}

Ergebnis

[example.FooExtension@40a4337a] created
[example.FooExtension@40a4337a] before each
test 1
[example.FooExtension@40a4337a] after each
[example.FooExtension@fa4c865] created
[example.FooExtension@fa4c865] before each
test 2
[example.FooExtension@fa4c865] after each
[example.FooExtension@3bd82cf5] created
[example.FooExtension@3bd82cf5] before each
test 3
[example.FooExtension@3bd82cf5] after each

Sie können sehen, dass jeder Test eine andere Instanz von Extension hat. Dies liegt daran, dass für jeden Test eine Instanz von SecondExtensionTest selbst generiert wird. BeforeAll und AfterAll funktionieren nicht, aber Sie müssen sie im Fall von "Lifecycle.PER_METHOD" statisch machen, wie beim Hinzufügen von "@ BeforeAll" zur Methode.

Für Lifecycle.PER_CLASS

Machen wir den Lebenszyklus des zweiten Erweiterungstests zu einer Form, in der eine Instanz nur einmal erstellt wird.

Quelle

SecondExtensionTest.java


+ @TestInstance(Lifecycle.PER_CLASS)
public class SecondExtensionTest {

    @RegisterExtension
    FooExtension fooExtension = new FooExtension();

    //Unterlassung
}

Ergebnis

[example.FooExtension@c730b35] created
[example.FooExtension@c730b35] before all
[example.FooExtension@c730b35] before each
test 1
[example.FooExtension@c730b35] after each
[example.FooExtension@c730b35] before each
test 2
[example.FooExtension@c730b35] after each
[example.FooExtension@c730b35] before each
test 3
[example.FooExtension@c730b35] after each
[example.FooExtension@c730b35] after all

Die Erweiterungsinstanz wird gemeinsam genutzt. Außerdem funktionieren Before All und After All jetzt. Wenn Sie auf diese Weise eine Erweiterung in einem nicht statischen Feld registrieren, hängt dies natürlich vom Lebenszyklus der ursprünglichen Testklasse ab.

Wenn Sie es richtig lesen, wird es geschrieben

https://junit.org/junit5/docs/current/user-guide/#extensions

Recommended Posts

Ich habe den Lebenszyklus der Erweiterung von JUnit Jupiter untersucht
Über den Android-Lebenszyklus
Ich habe die Quelle von ArrayList gelesen, die ich gelesen habe
Ich habe die Quelle von Integer gelesen
Ich habe die Quelle von Long gelesen
Ich habe die Quelle von Short gelesen
Ich habe die Quelle von Byte gelesen
Ich habe die Quelle von String gelesen
Ich habe den Ablauf der TCP-Kommunikation mit Spring Integration (Client Edition) untersucht.
Ich habe den Ablauf der TCP-Kommunikation mit Spring Integration (Server Edition) untersucht.
Ich habe die interne Verarbeitung von Retrofit untersucht
[Tag: 5] Ich habe die Grundlagen von Java zusammengefasst
Fassen Sie den Lebenszyklus von Java-Objekten zusammen, die bei der Android-Entwicklung berücksichtigt werden müssen
UCP-45060 Der Lebenszyklusstatus ist ungültig. Überprüfen Sie den Status des universellen Verbindungspools
Ich habe den Teil von java.net.URL # getPath überprüft
Ich habe die Grundlagen der Zeicheneingabe verstanden
Ich habe die Eigenschaften von Java und .NET verglichen
Überschreiben Sie den Inhalt der Konfiguration mit Spring-boot + JUnit5
Ich möchte den Inhalt der Absicht var_dump
Ich habe versucht, den Profiler von IntelliJ IDEA zu verwenden
Ich habe die Anzahl der Taxis mit Ruby überprüft
Probieren Sie Progate Free Edition [Java I]