In a Spring Boot app, I have this service:
@Service
@RequiredArgsConstructor
public class Foo {
@Value("${spring.profiles.active:}")
private String activeProfile;
public boolean stuff() {
System.out.println("Active profile: " + activeProfile);
return true;
}
}
When I start the app with -Dspring.profiles.active=bar
, and call the method stuff()
, the log displays Active profile: bar
, as expected.
I have a sample test class that looks like this :
@SpringBootTest
@ActiveProfiles("foo")
public class FooTest {
@Autowired
private Foo foo;
@Test
void fooTest() {
assertTrue(foo.stuff());
}
}
When I run this test, the log displays no active profile (Active profile :
).
Why @ActiveProfiles("foo")
doesn't work in that case ?
My final goal is that some of my SpringBootTest classes go through some code, while others don't, without adding a boolean test
method param.
Spring Boot version is 3.3.2
The problem is because of the order of Spring application lifecycle: active profiles are applied later than the injection of values into @Value annotated fields.
You can get these profiles from Environment, so you can change your service class to this:
@Service
@RequiredArgsConstructor
public class Foo {
private final Environment env;
public boolean stuff() {
String[] activeProfiles = env.getActiveProfiles();
System.out.println("Active profiles: " + String.join(", ", activeProfiles));
return true;
}
}
Note, that test class is unchanged.