Testing JPA entities using Spring Boot 2, JUnit 5 and Java 14

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
  1. There is no need to add the @RunWith(SpringRunner.class) annotation anymore.
  2. 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.
  3. 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”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s