Как я могу использовать @IfProfileValue для проверки активности профиля?
Так смущает @IfProfileValue
не имеет ничего общего с @Profile
или же @ActiveProfiles
, @Profile
проверяет, активен ли профиль, @ActiveProfiles
устанавливает их как активные, и @IfProfileValue
позволяет проверять вещи весной Environment
, Wut? Я бы осудил их всех и добавил бы новые @IfEnvironment
, @IfProfile
, а также @ActivateProfiles
,
Комментарий в сторону, как я могу использовать @IfProfileValue
определить, есть ли у меня активный профиль? В данный момент я не использую Spring Boot в этом проекте. Ответы должны показывать код, и мы будем предполагать, что я хочу, чтобы тест выполнялся, если профиль активирован как @ActiveProfiles( "test" )
,
Я старался @IfProfileValue(name = "activeProfiles", value = "test")
но кажется, что тест пропущен, что означает, что он не соответствует. Я собираюсь предположить, что проблема может быть связана с тем, что ActiveProfiles
это Collection
,
4 ответа
Так смущает
@IfProfileValue
не имеет ничего общего с@Profile
или же@ActiveProfiles
,
Это правильно, и я объяснил это подробно здесь: /questions/213222/ifprofilevalue-protiv-activeprofiles-v-kontekste-testa-spring/213223#213223
... который, я полагаю, вы уже видели, так как вы прокомментировали мой ответ вчера.
Причина того, что @IfProfileValue
не имеет ничего общего с @Profile
или же @ActiveProfiles
связано с эволюцией структуры. Смотрите ниже для более подробной информации.
@Profile
проверяет, активен ли профиль,@ActiveProfiles
устанавливает их как активные, и@IfProfileValue
позволяет проверять вещи веснойEnvironment
,
Эти утверждения не совсем верны, особенно последняя часть.
@Profile
используется для выборочного включения компонента (например, @Service
, так далее.), @Configuration
класс или @Bean
метод, если один из именованных профилей определения бина активен в Spring Environment
для ApplicationContext
, Эта аннотация не имеет прямого отношения к тестированию: @Profile
не должен использоваться на тестовом классе.
@ActiveProfiles
используется для определения того, какие профили определения бина (например, объявленные через @Profile
) должен быть активным при загрузке ApplicationContext
для интеграционного теста.
@IfProfileValue
не позволяет проверять вещи весной Environment
, Я не уверен, почему вы предполагаете это, так как ни одна из документации в Spring Framework не заявляет об этом. Как я уже говорил в вышеупомянутой теме:
Обратите внимание, что @IfProfileValue
был представлен в Spring Framework 2.0 задолго до того, как появилось понятие профилей определения бина, и @ActiveProfiles
Впервые был представлен в Spring Framework 3.1.
В вышеупомянутой теме я также указал следующее:
Термин "профиль", возможно, вводит в заблуждение при рассмотрении семантики для @IfProfileValue
, Ключ в том, чтобы думать о "тестовых группах" (таких как в TestNG) вместо "профилей". Смотрите примеры в JavaDoc для @IfProfileValue.
как я могу использовать
@IfProfileValue
определить, есть ли у меня активный профиль?
Это зависит, и... я предполагаю, что вы имеете в виду профиль определения бина, когда говорите "профиль".
Если вы используете @ActiveProfiles
чтобы установить профили определения бина для ваших тестов, вы не можете в настоящее время использовать @IfProfileValue
определить, активен ли профиль определения компонента, поскольку профили определения компонента настроены с помощью @ActiveProfiles
устанавливаются непосредственно в тесте ApplicationContext
а не как системное свойство Java.
Однако, если вы устанавливаете профили определения бина только через spring.profiles.active
свойство системы, тогда можно было бы использовать @IfProfileValue
определить, активен ли профиль определения компонента, так как @IfProfileValue
фактически работает со свойствами системы. Например, вы можете использовать следующее:
@IfProfileValue(name = "spring.profiles.active", value = "test")
Я старался
@IfProfileValue(name = "activeProfiles", value = "test")
но кажется, что тест пропущен, что означает, что он не соответствует.
Это не будет работать с тех пор activeProfiles
неверное имя свойства. Правильное имя системного свойства spring.profiles.active
, Увидеть AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME
для деталей.
Дело в том, что @IfProfileValue
не работает в гармонии с @ActiveProfiles
это известная проблема для команды Spring. Пожалуйста, обратитесь к следующим вопросам JIRA для получения более подробной информации и присоединиться к обсуждениям, если хотите.
- https://jira.spring.io/browse/SPR-7754
- https://jira.spring.io/browse/SPR-8982
- https://jira.spring.io/browse/SPR-11677
Надеюсь, это прояснит ситуацию для вас!
Сэм (автор Spring TestContext Framework)
Сэм прибил это. (А также тот факт, что это было принято и ответил лет назад)
Одна вещь, которую нужно добавить, это то, что если вы хотите передать Системные свойства в свой тест, их распространение на JVM, если вы используете инструмент сборки, такой как gradle, может потребовать дополнительного шага.
//build.gradle
tasks.withType(Test) {
systemProperties System.properties
}
И тогда дела как обычно в вашем интеграционном тесте
//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(){ ... }
}
Наконец, вы можете выполнить свои тесты из терминала с указанным вами свойством.
$> ./gradlew clean test -Drun.integration.tests=true
То, что мне нравится больше всего @IfProfileValue
над захватом System.property и проверкой assumeTrue/False
вручную это означает, что Spring Context не загружен (или пролетные / другие миграции, которые у вас могут быть), сохраняя быстрые юнит-тесты.
К сожалению, по моему опыту, тестовая зависимость от @IfProfileValue
@Test
@IfProfileValue(name="spring.profiles.active", values={"test"})
Будет работать, только если вы установите spring.profiles.active как свойство JVM, например: -Dspring.profiles.active="test"
@IfProfileValue just ignores spring.profiles.active from application.properties/yml.
При использовании junit5 можно условно включить тест на основе активного профиля:
@EnabledIf(expression =
"#{environment.acceptsProfiles(T(org.springframework.core.env.Profiles).of('someprofile'))}",
loadContext = true)
class MyTest {
...
}
Это проверяет, является ли активным и в отличие от проверки на
spring.profiles.active
свойство работает, если включено более одного профиля. Это проверяет, если
someprofile
находится среди активных в настоящее время профилей.
Чтобы сделать это более читабельным, можно использовать мета-аннотацию Spring. Сначала определите аннотацию
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@EnabledIf(expression =
"#{environment.acceptsProfiles(T(org.springframework.core.env.Profiles).of('someprofile'))}",
loadContext = true)
public @interface EnabledIfSomeProfile {
}
А затем используйте его на тестовых классах:
@EnableIfSomeProfile
class MyTest {
...
}