-->
One of the major bottlenecks in Digital transformation these days is technical debt. No Unit tests or legacy unit tests is one of them. One of the dominant frameworks for unit testing is Junit. Major industry player rely on version 4 of Junit to write unit test. Junit 5 is in market for quite some time even though migration of Junit 5 has not picked pace. This is due to lack of clear migration path for developers. In this exercise moving existing project in Junit 4 to Junit 5. It starts with basic spring boot project using Junit 4. Project will be a simple calculator application with dependency classes to see how mocking frameworks like Mockito is fitting along with Junit. Exercise guides you write unit test for this calculator application. It will then introduce Junit 5 in Junit 4 project. It needs to exclude Junit 4 dependencies. At last, you will migrate Junit 4 based test class to Junit 5. Please note that there is no backward compatibility between Junit 5 and Junit 4, to mitigate this Junit team created Junit vintage project to support Junit 4 test cases on top of Junit 5. Some of the salient features of Junit5 will help taking unit testing to next level are in form of parameterized test, dynamic test and assertion aggregation to name a few. If you just want to check out the project without going through steps you can download it from here https://github.com/developer-help/junit5-migration
Open Eclipse editor and create a maven project name it as unit4. Checkout image for reference. You need to click on New under File menu, select Maven project and select a simple archetype. You can think archetype as a template under maven ecosystem.
Once the project is created. Go to the explorer view in eclipse and open pom.xml file of this newly created project. Add dependencies to POM for spring-boot-starter-web and spring-boot-started-test. You can refer to below snippet for reference.
Check the version of spring boot included, go to start of the POM file and see the version of spring and spring boot. It needs to match as 2.0.3 as this version was having Junit 4 for unit testing. Your final POM will look like below
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>springbootjunit4groupId>
<artifactId>unit4artifactId>
<version>0.0.1-SNAPSHOTversion>
<packaging>jarpackaging>
<name>junit-4-applcationname>
<url>http://maven.apache.orgurl>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.0.3.RELEASEversion>
parent>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
properties>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
dependency>
dependencies>
project>
Spring boot project works on the concept of parent POM inheritance. Parent POM contains version dependencies entry for helper projects like Junit. Below snippet will help you understand why 2.0.3 was using Junit 4.
https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-test/2.0.3.RELEASE/spring-boot-test-2.0.3.RELEASE.pom Right side is of latest version,
Junit 4 dependency is still part of newer spring-boot-test project because of backward compatibility. It essentially means if there are existing Junit 4 test cases available in same project Junit’s will not break. In next few steps we will see how we will exclude Junit 4 fully and move to Junit 5 fully.
Create simple Java classes with names as Calculator, Multiplier, Adder and Subtractor. Once you add these classes you need to enrich them with functional code. To make it quicker, you can copy paste the code from below snippet in corresponding classes or refer the Github link provided at the top. Here you are creating main class and delegating classes. This is necessary to learn the concept of mocking which is essential in any commercial projects. It is because most of the projects are designed with separation of concerns in mind. This exercise is using spring as an IOC(Inversion of control) container java class created are injected as bean and autowired.
Create simple Java classes with names as Calculator, Multiplier, Adder and Subtractor. Once you add these classes you need to enrich them with functional code. To make it quicker, you can refer the Github link provided at the top. Here you are creating main class and delegating classes. This is necessary to learn the concept of mocking which is essential in any commercial projects. It is because most of the projects are designed with separation of concerns in mind. This exercise is using spring as an IOC(Inversion of control) container java class created are injected as bean and autowired.
You need to create test class call it CalculatorTest. To keep it simple you just copy paste the code snippet in the created test class. In this class you are using SpringBootTest annotation @RunWith(SpringJUnit4ClassRunner.class) annotation. Runwith Annotation is Junit 4 specific annotation. This annotation provides test run engine. You annotated dependency classes like Adder and Subtractor in class with MockedBean annotation. This annotation will create mocked instances of the dependency classes and inject it in the execution path during Junit run. This is least invasive way of injecting dependency otherwise you either have to create setter and getter in the Calculator class or create constructor accepting these dependencies. Above two approaches will not add any value rather increase boiler plate code. This strategy of MockedBean will keep code as close to production and still supporting unit test. In below snippet SpringJUnit4ClassRunner is used to run the test. This will allow us to autowire Spring dependencies in the test class and instantiate the application context for this during test execution. There are many runners available for Junit one of them is SpringJUnit4ClassRunner. Run the test case in eclipse with run as Junit test option doing right click on class, it will run with SpringJUnit4ClassRunner
In this step you are going to create new Junit 5 project. You go to context menu by right clicking in project explorer view of the unit4 project. Please refer below snippet to gain more clarity and give it new name sb-junit5
In this step you are going to create new Junit 5 project. You go to context menu by right clicking in project explorer view of the unit4 project. Please refer below snippet to gain more clarity and give it new name sb-junit5
As discussed above Junit Vintage engine was responsible for running Junit 4 tests. In this step you will exclude that dependency. In order to achieve this you open pom.xml of sb-junit5 project and change spring boot version to latest 2.2.3.RELEASE and exclude the Junit-vintage-engine dependency from spring boot started test dependency to use junit5 and Mockito. In order to do it faster you can copy the pom from git directly. Below image shows difference view for pom.xml before and after changes.
Open CalculatorTest from copied project and paste the snippet from Git link. There are certain things worth noting here. Import statement for Junit 5 and Junit 4 is different as Supporting classes have different package. Junit Runner class changed to SpringExtension. You have to use ExtendWith annotation instead of RunWith as per Junit 5. Junit 5 has got rid of RunWith annotation in this version as it has introduced this concept of ExtendWith, this concept is applicable for all other areas in Junit 5 where one can extend existing functionality coming out of the box. Thus giving user leverage to build something on top of existing stuff without reinventing the wheel. For example it provides you a mechanism to combine annotations from the package to given new meaning like you want to run certain tests for sanity vs full suite you can create a annotation to filter those test cases combining existing @Test Annotaion like @SanityTest. There is a change in test method having exception in annotation to assertion like below, it is using new method and lambda expression. We added new annotation DisplayName from Junit 5 to be more descriptive about methods what they are doing like below. There is no change to Mockito API though new version of Mockito has been added by parent pom of spring boot thus supporting Junit5 with Mockito out of the box. Try running the test class as Junit test.
This exercise covered how to move to new Junit 5 version from Junit 4 project. You learned how backward compatibility is ensured with Junit 4 in Junit 5; what packages needs to be imported with new Junit 5. You learned about new way of testing exceptions and usage of display name in Junit 5. You got brief about what to exclude from Pom in order to completely shut off Junit 4. There may be cases in your project where you are not inheriting from parent pom of spring boot in those cases these dependencies needs to be managed manually.
5 Benefits of GenAI in Talent Evaluation You Can’t Ignore in 2025