Mocking @Value
About
In Spring Boot applications, @Value("${...}") is commonly used to inject values from configuration properties. While this is convenient during runtime, testing code that depends on @Value fields requires special handling — especially when we want to mock or override these values during unit or integration tests.
What is @Value?
In Spring Boot, the @Value annotation is used to inject values from application.properties, environment variables, or system properties.
@Value("${scope.stepup.otp}")
private String stepUpOtpScope;Unit Testing (No Spring Context)
In unit tests, we don't start the Spring container, so dependency injection via @Value won't happen automatically. We have two options:
1. Set the Field via Reflection (Private Fields)
If the field is private, use Java reflection:
public class MyService {
@Value("${scope.stepup.otp}")
private String stepUpOtpScope;
public String getScope() {
return stepUpOtpScope;
}
}2. Use a Constructor or Setter (Public Fields or Refactored Code)
A better design is to inject properties via constructor or setter, which makes mocking easier:
Option 1: Use @Component + @Value on Constructor Parameter
Option 2: Use @Bean Method in Configuration Class
If MyService is not annotated with @Component, we can define a @Bean ourself:
Integration Testing (Using Spring Context)
When writing Spring Boot integration tests using @SpringBootTest, Spring will inject @Value properties. To override them:
1. Use @TestPropertySource or Spring Profiles
2. Use @DynamicPropertySource (for dynamic values or Testcontainers)
Use this when we need to set properties programmatically at runtime (common in integration tests with Testcontainers):
Last updated