Issue
Is it possible to add a "dynamic" property from a class to application.properties
before they are evaluated?
I want to achieve the following: find a free port on the system, inject it as property mockPort
into the spring lifecycle, and reuse this port to override a property from application.properties
using @TestPropertySource
, as follows:
@SpringBootTest
@TestPropertySource(properties = "web.client.url=localhost:${mockPort}/path")
public class MyWebTest {
//TODO how to write the port into ${mockPort} property?
private static final PORT = SocketUtils.findAvailableTcpPort();
@BeforeEach
public void init() {
MockWebServer mock = new MockWebServer();
mock.start(PORT);
}
@Test
public void test() {
service.runWebRequest();
}
}
The service under test can be any client that makes use of @Value("${web.client.url})
. And as the free port is found dynamically during runtime, I have to somehow inject it into that property.
How can I achieve this?
Solution
You can use Spring Framework's @DynamicPropertySource
for this purpose. It's described in this blog post.
In the case of MyWebTest
, the dynamic property source would look something like this:
@DynamicPropertySource
static void mockPortProperty(DynamicPropertyRegistry registry) {
registry.add("mockPort", () -> PORT);
}
Answered By - Andy Wilkinson
Answer Checked By - Cary Denson (JavaFixing Admin)