Spring Boot
JUnit
application.properties
testing
configuration

Override default Spring-Boot application.properties settings in Junit Test

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When working with Spring Boot applications, developers often need to test certain functionalities diverging from the application's default configurations. JUnit, a popular testing framework for Java, allows developers to write unit tests to ensure the correctness of their applications. In Spring Boot tests, overriding properties in application.properties is a common necessity. This article explores how to override default Spring Boot application properties in JUnit tests, providing detailed explanations and examples.

Spring Boot Testing Overview

Spring Boot provides an integrated test support through Spring's @SpringBootTest and other annotations that render tests more straightforward and effective:

  • @SpringBootTest: This annotation is used to load the complete application context.
  • @TestPropertySource: This annotation is used to override properties at test level.
  • @Value and Environment: These can be used to inject values or programmatically access property values.

Overriding Application Properties

When writing tests, there might be scenarios where you want the application to behave differently than its default mode. For example, you might want to set an in-memory database instead of an external database or use mock services. Here are methods to override properties:

Using @TestPropertySource

One of the simplest ways to define property overrides in Spring Boot tests using JUnit is the @TestPropertySource annotation. This annotation allows for easy overriding of properties.

java
1import org.junit.jupiter.api.Test;
2import org.springframework.boot.test.context.SpringBootTest;
3import org.springframework.test.context.TestPropertySource;
4
5@SpringBootTest
6@TestPropertySource(properties = {
7    "app.environment=test",
8    "spring.datasource.url=jdbc:h2:mem:testdb"
9})
10public class MyServiceTest {
11
12    @Test
13    public void contextLoads() {
14        // Test logic here
15    }
16}

Using @SpringBootTest with properties Attribute

If you're using @SpringBootTest, it directly supports setting inline properties, enabling overriding without an additional annotation:

java
1import org.junit.jupiter.api.Test;
2import org.springframework.boot.test.context.SpringBootTest;
3
4@SpringBootTest(properties = {
5    "app.environment=test",
6    "spring.datasource.url=jdbc:h2:mem:testdb"
7})
8public class MyServiceTest {
9
10    @Test
11    public void contextLoads() {
12        // Test logic here
13    }
14}

Using SpringBootTest.WebEnvironment

When testing specific layers of your application, such as when running tests as different web environments, you might need to override web-related properties.

java
1@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
2    "app.environment=test"
3})
4public class MyWebServiceTest {
5
6    @LocalServerPort
7    private int port;
8
9    @Test
10    public void testWebLayer() {
11        // Use 'port' to test REST endpoints.
12    }
13}

Creating a Custom application-test.properties File

Rather than inline properties, you can provide a separate application-test.properties file to the @TestPropertySource annotation:

java
1@SpringBootTest
2@TestPropertySource(locations = "classpath:application-test.properties")
3public class MyServiceTest {
4    ...
5}

Direct Property Setting via Programmatic Means

Sometimes properties might need programmatic approaches. Using Spring's Environment or setting up a DynamicPropertySource in conjunction with @TestConfiguration or @DynamicPropertySource may be the way to go.

java
1import org.junit.jupiter.api.Test;
2import org.springframework.boot.test.context.SpringBootTest;
3import org.springframework.context.annotation.Configuration;
4import org.springframework.test.context.DynamicPropertyRegistry;
5import org.springframework.test.context.DynamicPropertySource;
6
7@SpringBootTest
8public class MyServiceTest {
9
10    @DynamicPropertySource
11    static void dynamicProperties(DynamicPropertyRegistry registry) {
12        registry.add("app.environment", () -> "dynamic-test");
13        registry.add("spring.datasource.url", () -> "jdbc:h2:mem:otherdb");
14    }
15
16    @Test
17    public void contextLoads() {
18        // Test logic here
19    }
20}

Best Practices and Considerations

  1. Clear Test Configuration: Keep test configurations separate from application configurations. Use specific properties for testing (application-test.properties).
  2. Environment Specific: Ensure property overrides are relevant to the specific tests being run. Avoid unnecessary configurations that don't influence the test scenarios.
  3. Isolation and Independence: Tests should not depend on particular environments, ensure they're isolated and independently executable.
  4. Avoid Hardcoding Values in Tests: Use constants or reference utility methods to set properties dynamically, when possible.

Property Override Summary

MethodDescription
@TestPropertySourceOverrides properties using properties or a separate file.
@SpringBootTest(properties)Inline property overrides within the annotation.
SpringBootTest.WebEnvironmentConfigures web environment properties for test scenarios.
@DynamicPropertySourceProgrammatically configures properties in a dynamic manner.

Conclusion

Understanding how to override Spring Boot application properties in JUnit tests can enhance the reliability and coverage of your test suite. Whether using annotations or programmatically setting configurations, choosing the right method based on your test goals ensures streamlined, specific, and effective test cases.


Course illustration
Course illustration

All Rights Reserved.