See this example that demonstrates the issue:
@SpringBootTest
@ActiveProfiles("smoketest")
class SmokeTests {
@Autowired
private Environment environment;
@Test
void testProfileOrderSB25() {
Assertions.assertArrayEquals(new String[]{"smoketest", "dev"}, environment.getActiveProfiles());
}
@Test
void testProfileOrderSB23() {
Assertions.assertArrayEquals(new String[]{"dev", "smoketest"}, environment.getActiveProfiles());
}
}
The dev profile is activated using an EnvironmentPostProcessor.
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ProfileActivationEPP implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
environment.addActiveProfile("dev");
}
}
The different order demonstrated above will affect the order application-<profile>.properties are added and thus the value of overridden properties.
Comment From: mbhave
This is happening due to StandardEnvironment being used in tests instead of ApplicationServletEnvironment. When StandardEnvironment is used and a profile is added programmatically using addActiveProfile(), Spring Framework first gets all the profiles using the property spring.profiles.active. This means the profiles are added in the order smoketest and dev. With ApplicationServletEnvironment this side-effect isn't present and smoketest only gets added once the profiles are bound which results in the correct order. This affects 2.4.x as well but since the specialized environments were added in 2.5.x, we've decided to fix it in 2.5.x.
Comment From: dmak
Dear all,
Is there a good reason why the following code has been added at SpringBootContextLoader:126:
if (environment.getClass() == StandardEnvironment.class) {
environment = application.convertEnvironment(environment);
applicationEnvironment = true;
}
The issue is that the test I have which was working with Spring Boot 2.5.2 does not work with 2.6.1 because the necessary profile dev is not activated:
@SpringBootTest
@ActiveProfiles("dev")
public class FilterTest {
@Autowired
private FilterRegistrationBean<Filter> restrictionFilter;
...
Log:
DEBUG org.springframework.boot.ApplicationServletEnvironment - Activating profiles []
...
INFO [,,] [ ] 8584 --- [ main] a.s.b.f.FilterTest : No active profile set, falling back to default profiles: default
If modified this way it starts to work:
@SpringBootTest(properties = "spring.profiles.active:dev")
public class FilterTest {
...
The given test utilizes StandardServletEnvironment in 2.6.1 instead of StandardEnvironment in 2.5.2. Log for v2.5.2:
DEBUG org.springframework.core.env.StandardEnvironment - Activating profiles [dev]
...
INFO [,,] [ ] 14276 --- [ main] a.s.b.f.FilterTest : The following profiles are active: dev
Comment From: wilkinsona
@dmak There must be something else going on in your application that you haven't shared. Here's what I see with Spring Boot 2.6.1:
14:09:03.319 [main] DEBUG org.springframework.boot.ApplicationServletEnvironment - Activating profiles []
14:09:03.324 [main] DEBUG org.springframework.test.context.support.TestPropertySourceUtils - Adding inlined properties to environment: {spring.jmx.enabled=false, org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true, server.port=0}
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.1)
2021-12-10 14:09:03.621 INFO 62633 --- [ main] c.example.demo.Gh28530ApplicationTests : Starting Gh28530ApplicationTests using Java 1.8.0_252 on wilkinsona-a01.vmware.com with PID 62633 (started by awilkinson in /Users/awilkinson/dev/workspaces/spring-projects/spring-boot/2.6.x/gh-28530)
2021-12-10 14:09:03.622 INFO 62633 --- [ main] c.example.demo.Gh28530ApplicationTests : The following profiles are active: dev
If you would like us to investigate, please open a new issue and provide a complete yet minimal sample that reproduces the problem. You can share such a sample with us by zipping it up and attaching it to the issue you create or by pushing it to a separate repository on GitHub.
Comment From: dmak
I see that I was digging into a wrong place: SpringBootContextLoader.getEnvironment() always StandardEnvironment, so the issue is not in this very commit. I was debugging org.springframework.boot.context.config.Profiles#getActivatedProfiles() for a couple of hours until I get the idea. Actually I would have troubles creating a sample project to reproduce the problem as the initial project has tons of property files, YAMLs, and Java configurations... difficult to see where to start from.
Finally I got the following picture:
- The project defines the default profile in
application.yaml:
spring:
profiles:
active: dev
- The project has
application-test.propertieswhich reads:
spring.profiles.active=
- The particular test class has
@ActiveProfiles("dev").
The idea behind is that I want to disable all profiles for all tests, but enable (some of) them back for certain tests.
I have a feeling that now application-test.properties has a precedence over @ActiveProfiles("dev") because once I remove the line spring.profiles.active= the problematic test starts to work, but other (previously working) tests fail.
I think above is sort of this comment in issue #28739 and the dirty solution is to replace @ActiveProfiles("dev") with @SpringBootTest(properties = "spring.profiles.active:dev"). My personal opinion would be that class annotation should override the value in property/YAML file.
Comment From: mbhave
@dmak It's hard to tell what the issue could be without the sample. I'll try nonetheless. Could you provide more information on where the test profile is activated? It's not clear from the above message and for application-test.properties to be picked up the test profile would need to be active.
Also please create a new issue instead of using a closed one and we can continue the conversation there.
Comment From: buddyp450
Spring Framework first gets all the profiles using the property
spring.profiles.active. This means the profiles are added in the ordersmoketestanddev
sorry to necro this but would you happen to know how to log out this behavior? I'm having a very hard time finding it in spring