How can I use @IfProfileValue to test if a Profile is active?
Unfortunately, from my experience, test dependency on @IfProfileValue
@Test
@IfProfileValue(name="spring.profiles.active", values={"test"})
Will work only when you set spring.profiles.active as a JVM property, as: -Dspring.profiles.active="test"
@IfProfileValue just ignores spring.profiles.active from application.properties/yml.
Sam nailed it. (As well as the fact this was accepted and answered years back)
One thing to add is that if you'd like to pass System Properties through to your test, having them propagate through to the JVM if you are using a build tool like gradle may require an additional step.
//build.gradle
tasks.withType(Test) {
systemProperties System.properties
}
And then business as usual in your integration test
//MyIntegrationTest.class
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("integration")
@IfProfileValue(name = "run.integration.tests", value = "true")
public class MyIntegrationTest {
@Test
public void myTest(){ ... }
}
Finally you can execute your tests from the terminal with the property you specified.
$> ./gradlew clean test -Drun.integration.tests=true
The thing I like most about @IfProfileValue
over grabbing the System.property and checking assumeTrue/False
manually is that no Spring Context is loaded (or flyway/other migrations you may have) keeping unit tests fast.
So confusingly
@IfProfileValue
has nothing to do with@Profile
or@ActiveProfiles
.
That's correct, and I explained this in detail here: https://stackoverflow.com/a/23627479/388980
... which I'm assuming you have already seen, since you commented on my answer yesterday.
The reason that @IfProfileValue
has nothing to do with @Profile
or @ActiveProfiles
is due to the evolution of the framework. See below for further details.
@Profile
tests to see if a profile is active,@ActiveProfiles
sets them as active, and@IfProfileValue
allows you to check things in SpringEnvironment
.
These statements are not entirely correct, especially the last part.
@Profile
is used to selectively enable a component (e.g., @Service
, etc.), @Configuration
class, or @Bean
method if one of the named bean definition profiles is active in the Spring Environment
for the ApplicationContext
. This annotation is not directly related to testing: @Profile
should not be used on a test class.
@ActiveProfiles
is used to designate which bean definition profiles (e.g., those declared via @Profile
) should be active when loading an ApplicationContext
for an integration test.
@IfProfileValue
does not allow you to check things in the Spring Environment
. I'm not sure why you are assuming this, since none of the documentation in the Spring Framework states that. As I stated in the aforementioned thread:
Please note that @IfProfileValue
was introduced in Spring Framework 2.0, long before the notion of bean definition profiles, and @ActiveProfiles
was first introduced in Spring Framework 3.1.
In the aforementioned thread, I also pointed out the following:
The term 'profile' is perhaps misleading when considering the semantics for @IfProfileValue
. The key is to think about 'test groups' (like those in TestNG) instead of 'profiles'. See the examples in the JavaDoc for @IfProfileValue.
how can I use
@IfProfileValue
to detect whether i have a profile active?
That depends, and... I'm assuming you mean bean definition profile when you say "profile".
If you're using @ActiveProfiles
to set the bean definition profiles for your tests, you cannot currently use @IfProfileValue
to determine if a bean definition profile is active, since the bean definition profiles configured via @ActiveProfiles
are set directly in the test's ApplicationContext
and not as a Java system property.
However, if you are setting the bean definition profiles only via the spring.profiles.active
system property, then it would be possible to use @IfProfileValue
to determine if a bean definition profile is active, since @IfProfileValue
in fact works with system properties. For example, you could then use the following:
@IfProfileValue(name = "spring.profiles.active", value = "test")
I tried
@IfProfileValue(name = "activeProfiles", value = "test")
but that seems to have the test skipped, which means it's not matching.
That won't work since activeProfiles
is the incorrect property name. The correct system property name is spring.profiles.active
. See AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME
for details.
The fact that @IfProfileValue
does not work in harmony with @ActiveProfiles
is a known issue to the Spring team. Please consult the following JIRA issues for further details and to join in on the discussions if you'd like.
- https://jira.spring.io/browse/SPR-7754
- https://jira.spring.io/browse/SPR-8982
- https://jira.spring.io/browse/SPR-11677
Hope this clarifies the situation for you!
Sam (author of the Spring TestContext Framework)