Skip to content

Allow @DynamicPropertySource on non-static methods #24825

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
membersound opened this issue Mar 31, 2020 · 6 comments
Open

Allow @DynamicPropertySource on non-static methods #24825

membersound opened this issue Mar 31, 2020 · 6 comments
Labels
in: test Issues in the test module status: on-hold We can't start working on this issue yet type: enhancement A general enhancement

Comments

@membersound
Copy link

membersound commented Mar 31, 2020

While @DynamicPropertySource is great, it would be even better if it could be executed on each @Test method instead only one time at start of the test class.

For example: okhttp MockWebServer starts on a free random port. But each test needs its own MockWebServer as otherwise the state is preserved between test runs.

@SpringBootTest
public class MockTest implements BeforeEachCallback {
	private MockWebServer mockServer;

	//requires a fresh instance for each @Test method
	@Override
	public void beforeEach(ExtensionContext extensionContext) {
		mockServer = new MockWebServer();
	}

	//this is not possible as mockServer is not static!
	@DynamicPropertySource
	static void changePort(DynamicPropertyRegistry registry) {
		registry.add("my.app.base.url", () -> "http://localhost:" + mockServer.getPort()); 
	}
}

If I'd make the MockWebServer a static field, that won't work if multiple @Test classes make use of the mock. Eg assertEquals(1, mockServer.getRequestCount()); would only be valid for the first test method, as mockwebserver preserves the state then.

@bclozel bclozel transferred this issue from spring-projects/spring-boot Mar 31, 2020
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Mar 31, 2020
@sbrannen sbrannen added the in: test Issues in the test module label Mar 31, 2020
@sbrannen
Copy link
Member

Unfortunately, it is not currently possible to make the @DynamicPropertySource non-static, since the Spring TestContext Framework has no access to the test class instance when a ContextCustomizer is invoked (which is how the support for @DynamicPropertySource is implemented).

If we were to implement #16647, it may become possible, but at this time it is not possible.

Have you considered applying @DirtiesContext on a per-test-method basis to have the ApplicationContext reloaded for each individual test method?

@sbrannen sbrannen added the status: blocked An issue that's blocked on an external project change label Mar 31, 2020
@sbrannen
Copy link
Member

sbrannen commented Mar 31, 2020

@sbrannen sbrannen removed the status: waiting-for-triage An issue we've not yet triaged or decided on label Mar 31, 2020
@membersound
Copy link
Author

@DirtiesContext is a nice idea, anyhow this would reinitialize any beans inside the test. Eg database/testcontainers or similar, which might be quite expensive if recreated for each @Test.

@sbrannen
Copy link
Member

sbrannen commented Apr 7, 2020

@DirtiesContext is a nice idea, anyhow this would reinitialize any beans inside the test. Eg database/testcontainers or similar, which might be quite expensive if recreated for each @Test.

Well, if we were to support @DynamicPropertySource on non-static fields, how would that effectively be any different?

Spring components that consume the dynamic properties would typically be initialized with such dynamic properties when the ApplicationContext is created. Thus, without recreating the ApplicationContext, most (if not all) consumers of those dynamic properties would not see a change to their values.

Perhaps something like test-scoped beans (see #18606) would better suit your needs?

@membersound
Copy link
Author

Ok, so but testscoped beans have been closed without any implementation?

Is it maybe possible to declare my service that makes use of the "dynamic" @Value("${my.app.base.url}") as test-scoped? So that it rereads the dynamic property from application-context?

@sbrannen
Copy link
Member

sbrannen commented Apr 7, 2020

Ok, so but testscoped beans have been closed without any implementation?

That's correct. That issue was bulk closed due to lack of interest.

Is it maybe possible to declare my service that makes use of the "dynamic" @Value("${my.app.base.url}") as test-scoped? So that it rereads the dynamic property from application-context?

That's what I had in mind. Your use case reminded me of that test-scoped bean proposal.

And your use case would likely be a candidate for re-opening that issue. So feel free to request that it be reopened if you feel strongly about it, and we can revisit the idea.

@sbrannen sbrannen added status: on-hold We can't start working on this issue yet and removed status: blocked An issue that's blocked on an external project change labels Sep 26, 2023
@sbrannen sbrannen changed the title Allow @DynamicPropertySource on non-static fields Allow @DynamicPropertySource on non-static fields Sep 26, 2023
@sbrannen sbrannen changed the title Allow @DynamicPropertySource on non-static fields Allow @DynamicPropertySource on non-static methods Sep 26, 2023
@sbrannen sbrannen added the type: enhancement A general enhancement label Sep 26, 2023
@sbrannen sbrannen added this to the General Backlog milestone Sep 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: test Issues in the test module status: on-hold We can't start working on this issue yet type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants