JUnit Test cases and code coverage
In this section, we will learn about:
Writing Test with JUnit and Mockito
Writing Test using an in-memory database
JUnit is an open-source testing framework for Java. JUnit test cases are Java classes that contain one or more unit test methods.
Unit testing is a form of white-box testing, in which test cases are based on internal structure. The tester chooses inputs to explore particular paths and determines the appropriate output. The purpose of unit testing is to examine the individual components or pieces of methods/classes to verify functionality, ensuring the behavior is as expected.
Writing Test with Junit and Mockito
Mockito is a mocking framework used to mock an interface so that it can dummy its functionalities. Here, we will use mockito to mock our repository. So that the methods are used in the repository but the data are not saved in the database, as we are mocking the repository.
1) We will create a class in src/test named “YogaUserServiceTest”. Here we will test the methods in our service class in src/main. We will annotate the class name with “@SpringBootTest”. We will autowire our “YogaUserService” and use “@MockBean” to mock our repository.
2) Then we will use “@BeforeAll” for a before-all method. In this method, we set some variables and use methods as a prerequisite for the tests. Here, we will create an instance of a Yoga User. This before-all method is limited to just the class we have used in and in that entire class. Because we have used “@TestInstance(TestInstance.Lifecycle.PER_CLASS)”.
3) We need to import:
As we will use “when().thenReturn()” for returning “yogaUser” when we save “yogaUser” in our repository.
And finally use assertEquals(expected, actual), to check whether “service.<method>” is equal to the actual value of the demo user or not.
Writing Test using in-memory database
a) We are going to use H2 as our in memory database. For that we need to add some dependencies.
The in-memory database is different from mockito, as an in-memory database, data is stored on disk and does not mock anything.
b) Now we need to create an “application.yml” in the test too with datasource as H2.
c) We will create a test on the controller and make a class named “YogaUserControllerTest”.
d) Then we will autowire “YogaUserController” and create variables of “YogaUserReqDTO” and “YogaUserRespDTO”.
e) Then, we will create a new user by “YogaUserReqDTO” and return a response DTO after adding a user as seen in the figure below.
f) Now we will create a method of adding a user and annotate it with “@Test”.
g) We will use “assertThat” to check the response and the request data.
“import static org.assertj.core.api.Assertions.assertThat;”
Code coverage measures the lines of code in the main application used in testing.
To check your code coverage in IntelliJ. Click on “Run-> Run ‘Application’ with Coverage” and your application will run and pop out a window on write with analysis of code coverage.
There are 3 columns: Class, Methods, and Lines.
Which tells us what percentage and how many total classes, methods, and lines are used in testing.
You can reach each class and check which lines are not used. As used lines are represented by green on the left of the code window (beside line numbers) and not used lines are represented by red.
It is a good practice to keep code coverage as high as possible. Above 80% is considered good. But you should always aim higher.
Here, we have tested just Yoga Users’ controller and service and used only add method. So code coverage will show service and controller used as 100% but the method used 33% (as there are 3 methods). Total code coverage is calculated by taking all coverage into consideration.
Fig: Code coverage window.