JUnit5 Testing in Java
In this video we’re going to learn about the popular java testing framework JUnit5.
What is JUnit?
It is a simple open source framework to write and run repeatable tests. JUnit provides a simple API to test our java applications. The class or method we want to test is usually called as subject under test. so to write a test we simply create a java test class and use the JUnit API to make some assumptions towards the behavior of the subject under test and then jade verifies whether these assumptions are correct or not by either passing or failing the test.
On a high level JUnit5 is basically a combination of three different modules. JUnit platform is the module which provides an API to launch the test from either the IDE’s, build tools or console. So when you write a unit test using JUnit your IDE’s or build tool or console whatever platform you’re using uses this API inside the JUnit platform module to launch the tests.
Next we have the JUnit Jupiter module which provides an API to write our JUnit tests and extensions. If you want to write unit tests using JUnit 5 this is the module you need. The next module is JUnit vintage which provides a test engine implementation to support backward compatibility for tests written with JUnit3 and JUnitt4 so.
If you have some tests which are written using chain3 and 4 you can use this module to execute the stress without rewriting them in JUnit5 and lastly JUnit platform module enables some third-party testing frameworks to build their own API to write the tests and reuse the JUnit platform module to launch the tests so this is another interesting update which is part of JUnit 5.
First JUnit Test:
Now let’s go ahead and write our first test using JUnit5 so to write the unit test we are going to use a contact manager application i already prepared before as the name suggests this application manages the contact information and this is a very simple application which contains only two java classes the first one is a simple POJO class which contains three fields first name, last name and phone number and the next class is named contact manager so this is responsible to store the contact information.
This is a very simple application but provides enough functionality to cover all the features of JUnit5.
We need to download JUnit5 into our project
Testing Expectations using assertThrow():
Now let’s go ahead and test a negative scenario where the contact creation is failing. So we can test this case by providing some invalid input to the add contact method. We add a test where we are providing invalid values to first name, last name and phone number fields. So when i run the test again you can see that all the three threads are executed successfully.
Understanding JUnit Test Lifecycle:
Each JUnit test when it is executed will create a new instance of the test class and it follows different phases. Main use of these lifecycle phases is you may want to run some initialization tasks or some cleanup tasks when running the tests.
Before All phase where the methods will be executed before any of the test methods inside the test class and is executed once for the entire test class and usually this occurs before creating the instance of the test for this reason we have to mark the method as static or else. JUnit cannot execute this method so inside this method print a message so which should print this message before all the tests are executed. To understand create a method and add the Before All annotation and this message is printed at the time of test execution.
Before Each phase where the methods will be executed before each of the test method inside the test class. To understand create a new method and add Before Each annotation to this method. In this method Initialize contact manager class. Create a class variable contact manager and assign the variable to the contact manager object. JUnit will create a new instance of the class for each method so each test will work with its own copy of the test contact manager object .
After Each phase where the method will be executed after each test method inside the test class.
After All phase where some logic will be executed after all the test methods inside the class are executed.
The same applies also for the after each and after all annotations as in Before Each. To understand create a couple more methods and inside this method just print some messages .JUnit instantiates the test for each test method.
To change this behavior so that it will create only one instance of the class by adding the test instance annotation to the top of the class and to this annotation we can provide the value lifecycle dot per class by adding this annotation.
JUnit instantiate the test class only once in this case we can remove the static keyword for the after all and before all methods.
The next feature we are going to discuss is the conditional execution feature in JUnit. We can execute the test methods in our class based on a specific condition. JUnit provides us annotations enabled on OS and disabled noise and to this annotation we can pass on the operating system name as the annotation parameter.
Next feature we are going to learn about is assumptions. These are similar to conditional executions annotations but instead of executing the test conditionally we are going to perform the assertions inside the test conditionally that means if the assertion is successful then the test won’t fail but it will be aborted and won’t be executed further.
The next JUnit5 feature we are going to learn about is the repeated tests. In some situations you may need to run a specific test case multiple times maybe because the functionality has a bit of randomness to it. Imagine you are generating a random number between range maybe 1 to 10 or 1 to 50 and in those cases you can say to JUnit to repeat the test execution for a certain number of times. We can do that by using the repeated test annotation so this is just like a substitution for the test annotation but the test method will be executed for multiple repetitions.
Parameterized tests are similar to repeated tests but the difference is you can run the test repeatedly by giving different set of inputs to our tests. Similar to repeated tests we can replace the test annotation about the test method with the parameterized test annotation.
After adding the annotation we need a way to submit different set of inputs to the test method. We can do that with the help of some other annotations which is used together with the parameterized test annotation. So the first one is the value source annotation by using this annotation we can provide the input directly as a parameter value to the annotation and the value source annotations support different types of literal values like strings hint double float etc.
The next generate feature we are going to learn is the nested test so as the name suggests we can nest or group some tests inside our contact manager test class into an inner test class. so in ourexample we have multiple test methods which can be grouped together this may be some repeated tests or the parameterized test because they belong to the same category and if we organize these tests into their own classes then the task class will look much more clean and well organized so this is the main reason for using the nested class to make the test more organized.
The life cycle of nested test class is a bit different than the normal test class. In the nested classes we are allowed to only use the before each and after each annotations but not before all and after all because java won’t allow static members inside the inner classes. however if you want to use the beforeall and after all annotations you can change the instance life cycle by adding the test instance annotation with life cycle value as per class.
So now let’s discuss the last JUnit annotation of this course that is the disabled test you can use this annotation to disable some tests from executing in our test suite so it’s not generally encouraged to use this annotation until it’s really necessary because there’s a chance that you will forget to remove the annotation after adding it and the test will be disabled forever which is not so good.