Как я могу использовать @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 для получения более подробной информации и присоединиться к обсуждениям, если хотите.

Надеюсь, это прояснит ситуацию для вас!

Сэм (автор 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 {
 ...
}
Другие вопросы по тегам