@Before vs @BeforeClass vs @BeforeEach vs @BeforeAll

1. Einleitung

In diesem kurzen Tutorial werden wir die Unterschiede zwischen den Annotationen @Before , @BeforeClass , @BeforeEach und @BeforeAll in JUnit 4 und 5 erläutern - mit praktischen Beispielen für deren Verwendung.

Wir werden auch kurz auf ihre @ Nach ergänzenden Anmerkungen eingehen .

Beginnen wir mit JUnit 4.

2. @Vorher

Mit der Annotation @Before annotierte Methoden werden vor jedem Test ausgeführt. Dies ist nützlich, wenn Sie allgemeinen Code ausführen möchten, bevor Sie einen Test ausführen.

Sehen wir uns ein Beispiel an, in dem wir eine Liste initialisieren und einige Werte hinzufügen:

@RunWith(JUnit4.class) public class BeforeAndAfterAnnotationsUnitTest { // ... private List list; @Before public void init() { LOG.info("startup"); list = new ArrayList(Arrays.asList("test1", "test2")); } @After public void teardown() { LOG.info("teardown"); list.clear(); } }

Beachten Sie, dass wir auch eine andere mit @After kommentierte Methode hinzugefügt haben , um die Liste nach der Ausführung jedes Tests zu löschen.

Fügen wir danach einige Tests hinzu, um die Größe unserer Liste zu überprüfen:

@Test public void whenCheckingListSize_thenSizeEqualsToInit() { LOG.info("executing test"); assertEquals(2, list.size()); list.add("another test"); } @Test public void whenCheckingListSizeAgain_thenSizeEqualsToInit() { LOG.info("executing another test"); assertEquals(2, list.size()); list.add("yet another test"); }

In diesem Fall ist es wichtig sicherzustellen, dass die Testumgebung ordnungsgemäß eingerichtet ist, bevor Sie jeden Test ausführen, da die Liste bei jeder Testausführung geändert wird.

Wenn wir einen Blick auf die Log - Ausgabe nehmen wir überprüfen können , dass die init und Teardown - Methoden einmal pro Test durchgeführt wurden:

... startup ... executing another test ... teardown ... startup ... executing test ... teardown

3. @BeforeClass

Wenn wir vor jedem Test eine teure gemeinsame Operation ausführen möchten, ist es vorzuziehen, sie nur einmal auszuführen, bevor alle Tests mit @BeforeClass ausgeführt werden . Einige Beispiele für häufig teure Vorgänge sind das Erstellen einer Datenbankverbindung oder das Starten eines Servers.

Erstellen wir eine einfache Testklasse, die die Erstellung einer Datenbankverbindung simuliert:

@RunWith(JUnit4.class) public class BeforeClassAndAfterClassAnnotationsUnitTest { // ... @BeforeClass public static void setup() { LOG.info("startup - creating DB connection"); } @AfterClass public static void tearDown() { LOG.info("closing DB connection"); } }

Beachten Sie, dass diese Methoden statisch sein müssen , damit sie ausgeführt werden, bevor die Tests der Klasse ausgeführt werden.

Fügen wir wie zuvor auch einige einfache Tests hinzu:

@Test public void simpleTest() { LOG.info("simple test"); } @Test public void anotherSimpleTest() { LOG.info("another simple test"); }

Dieses Mal, wenn wir einen Blick auf die Log - Ausgabe nehmen wir überprüfen können , dass die Einrichtung und tearDown Methoden nur einmal ausgeführt wurden:

... startup - creating DB connection ... simple test ... another simple test ... closing DB connection

4. @BeforeEach und @BeforeAll

@BeforeEac h und @BeforeAll sind die JUnit 5-Äquivalente von @Before und @BeforeClass . Diese Anmerkungen wurden mit klareren Namen umbenannt, um Verwirrung zu vermeiden.

Lassen Sie uns unsere vorherigen Klassen mit diesen neuen Annotationen duplizieren, beginnend mit den Annotationen @BeforeEach und @AfterEach :

@RunWith(JUnitPlatform.class) class BeforeEachAndAfterEachAnnotationsUnitTest { // ... private List list; @BeforeEach void init() { LOG.info("startup"); list = new ArrayList(Arrays.asList("test1", "test2")); } @AfterEach void teardown() { LOG.info("teardown"); list.clear(); } // ... }

Wenn wir Protokolle überprüfen, können wir bestätigen, dass dies auf die gleiche Weise funktioniert wie bei den Annotationen @Before und @After :

... startup ... executing another test ... teardown ... startup ... executing test ... teardown

Lassen Sie uns abschließend dasselbe mit der anderen Testklasse tun, um die Annotationen @BeforeAll und @AfterAll in Aktion zu sehen:

@RunWith(JUnitPlatform.class) public class BeforeAllAndAfterAllAnnotationsUnitTest { // ... @BeforeAll public static void setup() { LOG.info("startup - creating DB connection"); } @AfterAll public static void tearDown() { LOG.info("closing DB connection"); } // ... }

Und die Ausgabe ist die gleiche wie bei der alten Anmerkung:

... startup - creating DB connection ... simple test ... another simple test ... closing DB connection

5. Schlussfolgerung

In diesem Artikel haben wir die Unterschiede zwischen den Annotationen @Before , @BeforeClass , @BeforeEach und @BeforeAll in JUnit gezeigt und wann sie jeweils verwendet werden sollten.

Wie immer ist der vollständige Quellcode der Beispiele auf GitHub verfügbar.