Overview
In this brief tutorial, we’ll explain the differences between the annotations @Before, @BeforeClass, @BeforeEach, and @BeforeAll in JUnit 4 and 5. We’ll provide practical examples to illustrate their usage. Additionally, we’ll touch upon their complementary @After annotations. Let’s start with JUnit.
@Before
The @Before annotation in JUnit 4 is used to execute a method before each test in the class. This is particularly useful for setting up test environments, such as initializing objects or configuring test-specific settings.
Here’s an example where we initialize a list and add some values to it:
@RunWith(JUnit4.class)
public class BeforeAndAfterAnnotationsUnitTest {private List<String> list;
@Before
public void setUp() {
System.out.println(“Initializing test environment…”);
list = new ArrayList<>(Arrays.asList(“item1”, “item2”));
}@After
public void tearDown() {
System.out.println(“Cleaning up test environment…”);
list.clear();
}@Test
public void testListSize() {
System.out.println(“Running testListSize…”);
assertEquals(2, list.size());
list.add(“newItem”);
}@Test
public void testListSizeAfterModification() {
System.out.println(“Running testListSizeAfterModification…”);
assertEquals(2, list.size());
list.add(“anotherItem”);
}
}
Explanation:
- The setUp() method runs before each test to initialize the list.
- The tearDown() method ensures the list is cleared after each test, resetting the environment for the next test.
Log output:
Initializing test environment…
Running testListSize…
Cleaning up test environment…
Initializing test environment…
Running testListSizeAfterModification…
Cleaning up test environment…
@BeforeClass
The @BeforeClass annotation is used when you need to execute a setup operation once before any tests in the class are run. This is ideal for expensive operations like creating a database connection or initializing a server.
Here’s an example:
@RunWith(JUnit4.class)
public class BeforeClassAndAfterClassAnnotationsUnitTest {@BeforeClass
public static void setUpClass() {
System.out.println(“Setting up shared resources…”);
// Simulate creating a database connection
}@AfterClass
public static void tearDownClass() {
System.out.println(“Tearing down shared resources…”);
// Simulate closing a database connection
}@Test
public void testExample() {
System.out.println(“Running testExample…”);
}@Test
public void testAnotherExample() {
System.out.println(“Running testAnotherExample…”);
}
}
Explanation:
- The setUpClass() method initializes shared resources once for all tests.
- The tearDownClass() method releases those resources after all tests are complete.
Log output:
Setting up shared resources…
Running testExample…
Running testAnotherExample…
Tearing down shared resources…
@BeforeEach and @BeforeAll
In JUnit 5, the annotations @BeforeEach and @BeforeAll replace @Before and @BeforeClass, respectively. They provide clearer naming conventions for better readability and understanding.
Using @BeforeEach and @AfterEach
import org.junit.jupiter.api.*;
class BeforeEachAndAfterEachAnnotationsUnitTest {
private List<String> list;
@BeforeEach
void setUp() {
System.out.println(“Initializing test environment…”);
list = new ArrayList<>(Arrays.asList(“item1”, “item2”));
}@AfterEach
void tearDown() {
System.out.println(“Cleaning up test environment…”);
list.clear();
}@Test
void testListSize() {
System.out.println(“Running testListSize…”);
Assertions.assertEquals(2, list.size());
list.add(“newItem”);
}@Test
void testListSizeAfterModification() {
System.out.println(“Running testListSizeAfterModification…”);
Assertions.assertEquals(2, list.size());
list.add(“anotherItem”);
}
}
Log output:
Initializing test environment…
Running testListSize…
Cleaning up test environment…
Initializing test environment…
Running testListSizeAfterModification…
Cleaning up test environment…
Using @BeforeAll and @AfterAll
import org.junit.jupiter.api.*;
class BeforeAllAndAfterAllAnnotationsUnitTest {
@BeforeAll
static void setUpClass() {
System.out.println(“Setting up shared resources…”);
}@AfterAll
static void tearDownClass() {
System.out.println(“Tearing down shared resources…”);
}@Test
void testExample() {
System.out.println(“Running testExample…”);
}@Test
void testAnotherExample() {
System.out.println(“Running testAnotherExample…”);
}
}
Log output:
Setting up shared resources…
Running testExample…
Running testAnotherExample…
Tearing down shared resources…
In this article, we showed the differences between the @Before, @BeforeClass, @BeforeEach and @BeforeAll annotations in JUnit and when each of them should be used.