In this article we will be looking at how to get started with testing JPA entities and the repository layer using Spring Boot 2.2 , JUnit 5 and Java 14. I have written a similar post here which uses Spring 1.5, JUnit 4 and Java 8. As the changes are significant I decided to keep them separate instead of updating that post.
I will be focusing mostly about the changes I had to make to the code to upgrade the libraries mentioned above. You can find the complete source code on github here.
Let us consider the same example of One-Many relation between SocialMediaSite and a User.
The @DataJpaTest
This remains the key ingredient behind running the JPA related tests in Spring Boot. @DataJpaTest disables full auto configuration and applies configuration related to JPA tests only. This concept hasn’t changed between Spring Boot 1.5 and 2.x. Now, let’s take a look at the areas where the code needed modifications.
Changes to the pom.xml
Upgrading the spring boot version to 2.2.6
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent>
Upgrading java version to 14
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>14</java.version> </properties>
Upgrading the dependency section to exclude JUnit 4
The spring-boot-starter-test dependency includes the vintage JUnit 4 and JUnit 5 dependencies.Since we will be using JUnit 5, we will exclude the vintage one.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency>
Junit 5 consists of 3 different sub projects – The JUnit engine , JUnit vintage ( Junit 3 and 4) and JUnit Jupiter( JUnit5). All JUnit 5 annotations reside in org.junit.jupiter.api package.
Support for preview features in Java 14
<plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <release>14</release> <compilerArgs> <arg>--enable-preview</arg> </compilerArgs> <forceJavacCompilerUse>true</forceJavacCompilerUse> <parameters>true</parameters> </configuration> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <argLine>--enable-preview</argLine> </configuration> </plugin>
Use of the Record type
Record type has been added as a preview feature in Java 14. The EmailAddress class has now been modified as a Record type. This was a value object before.
public record EmailAddress(String emailAddress) { public static final Pattern VALID_EMAIL_ADDRESS_REGEX = Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE); public EmailAddress { Assert.isTrue(isValid(emailAddress), "Email Address is Invalid !"); } private static boolean isValid(String emailAddress) { return emailAddress != null ? VALID_EMAIL_ADDRESS_REGEX.matcher(emailAddress).matches() : false; } }
Changes to the Test classes
- There is no need to add the @RunWith(SpringRunner.class) annotation anymore.
- The @Before annotation has been now replaced with @BeforeEach to perform any kind of setup before each test. Similarly the @After has been replaced with @AfterEach.
- The @Rule and @ExpectedException had been removed from JUnit5. The test classes have been refactored to reflect the same. The assertThrows and assertEquals method from the JUnit5 library have been used instead.
@Test public void testShouldReturnExceptionForInvalidEmailAddress() { var exception = assertThrows(IllegalArgumentException.class, () -> new EmailAddress("test@.com")); assertEquals(exception.getMessage(), "Email Address is Invalid !"); }
The assertThrows method takes a functional interface, Executable as second parameter. We pass the block of code that needs to be executed to Executable.
Conclusion
The @DataJpaTest helps us to test the JPA entities and the repository layer. This is also called as test slicing as we are testing only the JPA components.The @DataJpaTest annotation contains @ExtendWith(SpringExtension.class) which integrates the Spring Testing framework with JUnit 5 model.
We have not explored many features of JUnit5 in this example but the combination of Spring Boot’s testing features and JUnit5 does make a powerful combination.
One thought on “Testing JPA entities using Spring Boot 2, JUnit 5 and Java 14”