JUnit 5 - Writing Tests
Tags: java, testing, tutorial, beginners
Published: 2021-10-30 12:18:55

In [JUnit 5 - Introduction](https://dev.to/chathurashmini/junit-5-introduction-2lpa) we talked about JUnit and we wrote a really simple test case. In this tutorial we are going to dive in-depth to write more complex test methods.


#JUnit Test Lifecycle 💫

In JUnit it is not that you only have the annotation `@Test` for test methods. There may be cases where you have to run a test before all the other tests. Or you might have a test method to run before executing every other test method. Or you might have a test method to run when all the other test methods have executed. Not to worry, cause JUnit covers all these scenarios 😃

There are 5 phases that a test method can have. They are as follows;
* `@BeforeAll`
* `@BeforeEach`
* `@Test`
* `@AfterEach`
* `@AfterAll`


##@BeforeAll

Test methods marked with `@BeforeAll` annotation get executed before any of the test methods that are available in the Test class.
Let's write a simple test method using above annotation.

```java
@BeforeAll
public static void TestBeforeAll () {
    System.out.println("Should print BEFORE executing any other tests");
}

@Test
public void TestBeforeAllSuccess() {
    System.out.println("Should print AFTER executing TestBeforeAll () method");
}
```

As you can see here I have added two test methods. `TestBeforeAll ()` is with the annotation `@BeforeAll` and `TestBeforeAllSuccess()` is a normal test method. Now when we run the program `TestBeforeAll ()` executes first. Which means your output should look like this,
![2_testBeforeAll](https://raw.githubusercontent.com/chathuRashmini/Blog-Images/main/JUnit/2_testBeforeAll.PNG?token=APOCKO4U4M2YJZBUP4LHOULBPUYYY)


##@BeforeEach

Test methods marked with `@BeforeEach` annotation get executed before each of the test methods include in the Test class.

If you can remember in both test methods `TestAddEmployee()` and `throwRuntimeExceptionWhenFirstNameIsNull()`, I used the line,
`ManageEmployees employees = new ManageEmployees();`
Hence, there is repetition of same code line. We can avoid this by running the above line inside a new test method using the annotation `@BeforeEach`. Which mean this line will execute before the execution of each and every tests available in the test class.

```java
ManageEmployees employees;

@BeforeAll
public static void TestBeforeAll () {
    System.out.println("Should print BEFORE executing any other tests");
}

@BeforeEach
public void TestBeforeEach() {
    ManageEmployees employees = new ManageEmployees();
    System.out.println("Execute BEFORE EACH test method");
}

@Test
public void TestBeforeAllSuccess() {
    System.out.println("Should print AFTER executing TestBeforeAll () method");
}
```
In the above code I have added print statements for you to easily understand the order of test method execution 😁 Check the figure below to see the execution order of test methods.
![3_testBeforeEach](https://raw.githubusercontent.com/chathuRashmini/Blog-Images/main/JUnit/3_testBeforeEach.PNG?token=APOCKOZNG3OEDUVL5RINYUTBPUY2O)


##@Test

Yes, you know this annotation since we used it in the previous tutorial 😎 But let's try out a bit complex one 🤯 What about writing a test to validate inputs? That means you know that we don't let to keep any attribute (first_name, last_name, or contact_number) empty. We can write separate test methods to throw exceptions when any of the above fields is empty.

```java
@Test
@DisplayName("Object should not create when first_name is null")
public void throwRuntimeExceptionWhenFirstNameIsNull() {
    ManageEmployees employees = new ManageEmployees();
    Assertions.assertThrows(RuntimeException.class, () -> {
        employees.addEmployee(null, "Cullen", "0123456789");
    });
    System.out.println("Number of Employees: " + employees.getEmployees().size());
}
```

According to the above code, it throws a Runtime Exception when you try to create an object with an empty first name and do not create the object. I added the print statement so that you can clearly see that the object is not created. Look at the terminal below.

![14_testTest](https://raw.githubusercontent.com/chathuRashmini/Blog-Images/main/JUnit/14_testTest.PNG?token=APOCKO2HJ7FAO4XHRVNNLATBPUZAY)

You can see that the number of employees is zero, which means that object is not created just like we expected 🙂

> The `@DisplayName` in above code is a custom name that you can provide for a test method to increase the readability apart from the test method name.

Now I have a task for you 🥴 Try to write test methods by yourself to throw exceptions when last name and contact number is given as empty. Don't panic, it's very simple. You got this 😌


##@AfterEach 

Test methods marked with `@AfterEach` annotation get executed  after each test method inside the Test class. Look at the two test methods I have added.

```java
@Test
public void TestAfterEachSuccess() {
    System.out.println("Should print BEFORE executing TestAfterEach () method");
}
    
@AfterEach
public void TestAfterEach() {
    System.out.println("Should print AFTER the execution of EACH test method.");
}
```

Now let's run and see how the test methods execution happens.

![4_testAfterEach](https://raw.githubusercontent.com/chathuRashmini/Blog-Images/main/JUnit/4_testAfterEach.PNG?token=APOCKO3UQQLMNFKCRKRJSP3BPUZCU)

As you can see `TestAfterEach()` executes after the execution of each and every test method.


##@AfterAll

Test methods marked with `@AfterAll` annotation get executed after all the test methods in the Test class are finished executing.

```java
 @AfterAll
public static void TestAfterAll() {
    System.out.println("Should execute AFTER ALL the test methods");
}
```

![5_testAfterAll](https://raw.githubusercontent.com/chathuRashmini/Blog-Images/main/JUnit/5_testAfterAll.PNG?token=APOCKO62TEFB5OJL4QOB4ALBPUZEI)

As you can see the test method `TestAfterAll()` has executed after all the other test methods are executed.


Those are the *five phases of Test Lifecycle*. The main use of this lifecycle is to perform initialization tasks or cleanup tasks.
1. `@BeforeAll` and `@BeforeEach`: to perform initialization tasks for tests.
2. `@AfterEach` and `@AfterAll`: to perform cleanup tasks for tests.


With that we came to the end of this tutorial. You can learn how to write repeatable tests and conditional tests in the next tutorial 😎