The @Value annotation injects externalized properties into a Spring Boot application. The field’s value is usually read from the application.properties
or application.yml
file. While @Value eases the reading of externalized properties, it can present challenges during testing. In this article, we cover how to mock the @Value field in Spring Boot during both integration and unit testing.
Overwrite @Value During Integration Testing
To mock, or more precisely, overwrite the @Value
during integration testing, you can create a separate resources
directory, add an application.properties
file, and set a desired value in it. For instance, let’s assume we have the following property:
api.endpoint=https://eris.madadipouya.com/v1/weather/currentbyip
We want to overwrite this value during integration testing. To achieve this, as mentioned, we only need to create the application.properties
file and then set the desired value:
api.endpoint=https://dummyjson.com/test
During testing, you can access the property as usual.
@SpringBootTest
class WeatherApiIntegrationTest {
@Autowired
private WeatherApi weatherApi;
@Test
void testGetWeatherApiEndpointAddress() {
String result = weatherApi.getApiEndpoint();
assertEquals("https://dummyjson.com/test", result);
}
}
Mock @Value During Unit Testing
It is also possible to mock the @Value
field during unit testing, but it is a bit trickier.
To achieve that, we need to use ReflectionTestUtils
as shown below:
@InjectMocks
private WeatherApi weatherApi;
@BeforeEach
void initialize() {
ReflectionTestUtils.setField(weatherApi, "apiEndpoint", "https://weather-api.com");
}
The first argument is the object under test. The second argument is the name of the field whose value we aim to overwrite, and the last argument is the desired value. Here’s the full example:
@ExtendWith(MockitoExtension.class)
class WeatherApiTest {
@InjectMocks
private WeatherApi weatherApi;
@BeforeEach
void initialize() {
ReflectionTestUtils.setField(weatherApi, "apiEndpoint", "https://weather-api.com");
}
@Test
void testGetWeatherApiEndpointAddress() {
String result = weatherApi.getApiEndpoint();
assertEquals("https://weather-api.com", result);
}
}
Conclusion
In this article, we covered how to mock the @Value field in Spring Boot during integration and unit testing. For integration testing, you only need to create a test application.properties
file. However, unit testing requires explicitly overwriting the value using the ReflectionTestUtils
class. As always, the tutorial’s code is available on the Geeky Hacker GitHub repository.
Inline/featured images credits
- Featured image by Sean Stratton on Unsplash