Ondra Žižka
Ondra Žižka

Reputation: 46806

JUnit parametrized test with parametrized Spring ApplicationContext configuration

SpringBoot 2.2.11, JUnit 5.
My app has several environments. I have a test that tests some conditions in those environments rather than the application itself.

Therefore I want to reuse the same test method, but run it against different environments, as per environment variables / system properties.

So far, it is hard-coded:

@SpringBootTest(properties = ["app.env=test"])
class EnvTest {
    @Test fun test01() {...}
}

And I want to use something like @ParameterizedTest.

@SpringBootTest(properties = ["app.env=test"])
class EnvTest {
    @ParameterizedTest
    @ValueSource(strings = {"TEST", "PROD"})
    fun configCheck(env: String) {
        // Made-up for illustration
        spring.context.properties.put("app.env", env)
    }
}

Except, these parameters come too late, when the context is already created, and can't be taken into account by the test context manager. I want the parameters to be applied to the context creation.

All I could find so far to parametrize the context at runtime enables me to parametrize the beans - i.e. it's rather for app config rather than test config, like, @ContextConfiguration, or @ConfigurationProperties. Of course, I could also use profiles, and run a few times. But I prefer one run.

It seems to me that it's not possible, because what I want is at method level, but context creation can only be controlled at class level. So I can put the test to a base class, have several subclasses, and choose to run these based on the runtime parameters. But that's not as ellegant as @ParametrizedTest :)

Is this possible with SpringBoot 2.2.x?
Maybe @ProfileValueSource could be used somehow?

Upvotes: 2

Views: 1509

Answers (1)

Sam Brannen
Sam Brannen

Reputation: 31197

No, it is not currently possible to parameterize a JUnit Jupiter test (method or class) with Spring bean definition profiles.

Related issues:

  1. Spring: Introduce support for executing a test class with different sets of profiles
  2. Spring: Support @ContextConfiguration at method level
  3. Spring: Support @ActiveProfiles at method level
  4. JUnit Jupiter: Introduce extension API for container templates

Ideally, JUnit Jupiter will introduce support for container templates at which point Spring Framework will be able to build on top of that support in order to allow an ApplicationContext to be created with various active profiles for parameterized invocations of the test class.

In the interim, the easiest way to achieve your goal is probably to define a base test class with common Spring configuration and common test methods and then introduce a subclass per combination of active profiles you wish to test. Annotating the base test class with @DirtiesContext would likely be beneficial since the contexts created for each subclass will likely not be used multiple times.

Upvotes: 4

Related Questions