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?
CodePudding user response:
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);
}
CodePudding user response:
Maybe you prefer to start a single MockWebServer for all test classes, instead of starting a new server for each test method. When this class is initialized, the static block starts a server and sets a system property to the server URL. System properties override properties from the application.properties file.
@TestConfiguration
public class MockWebServerConfiguration {
private static final MockWebServer mockWebServer = new MockWebServer();
static {
int port = SocketUtils.findAvailableTcpPort();
mockWebServer.start(port);
System.setProperty("web.client.url", "localhost:" port "/path");
}
}
To include this configuration class in your integration test, annotate your test class with:
@Import(MockWebServerConfiguration.class)
