Профиль Spring-boot по умолчанию для интеграционных тестов


94

Spring-boot использует профили Spring ( http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html ), которые позволяют, например, иметь отдельную конфигурацию для разных сред. Один из способов использования этой функции - настроить тестовую базу данных для использования в интеграционных тестах. Интересно, однако, необходимо ли создавать свой собственный профиль «test» и явно активировать этот профиль в каждом тестовом файле? Сейчас я делаю это следующим образом:

  1. Создайте application-test.properties внутри src / main / resources
  2. Напишите там тестовую конфигурацию (пока только имя базы данных)
  3. В каждый тестовый файл включают:

    @ActiveProfiles("test")
    

Есть ли более умный / краткий способ? Например, тестовый профиль по умолчанию?

Изменить 1: этот вопрос относится к Spring-Boot 1.4.1

Ответы:


93

Насколько мне известно, нет ничего, что могло бы напрямую удовлетворить ваш запрос, но я могу предложить предложение, которое могло бы помочь:

Вы можете использовать свою собственную тестовую аннотацию, которая представляет собой метааннотацию, содержащую @SpringBootTestи@ActiveProfiles("test") . Таким образом, вам по-прежнему нужен специальный профиль, но избегайте разброса определения профиля по всему вашему тесту.

Эта аннотация будет по умолчанию для профиля, testи вы можете переопределить профиль с помощью мета-аннотации.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@SpringBootTest
@ActiveProfiles
public @interface MyApplicationTest {
  @AliasFor(annotation = ActiveProfiles.class, attribute = "profiles") String[] activeProfiles() default {"test"};
}

1
Как это можно использовать для объявления нескольких активных профилей, которые будут использоваться аннотацией?
Payne

Простое и аккуратное решение.
Виньеш

53

Другой способ сделать это - определить базовый (абстрактный) тестовый класс, который будут расширять ваши фактические тестовые классы:

@RunWith(SpringRunner.class)
@SpringBootTest()
@ActiveProfiles("staging")
public abstract class BaseIntegrationTest {
}

Бетонный тест:

public class SampleSearchServiceTest extends BaseIntegrationTest{

    @Inject
    private SampleSearchService service;

    @Test
    public void shouldInjectService(){
        assertThat(this.service).isNotNull();
    }
} 

Это позволяет извлекать не только @ActiveProfilesаннотацию. Вы также можете представить себе более специализированные базовые классы для различных видов интеграционных тестов, например, уровень доступа к данным или уровень обслуживания, или для функциональных особенностей (общие @Beforeили @Afterметоды и т. Д.).


43

Вы можете поместить файл application.properties в папку test / resources. Там вы устанавливаете

spring.profiles.active=test

Это своего рода тестовый профиль по умолчанию при запуске тестов.


Я использую эту запись в своих тестовых примерах, если не хочу устанавливать @ActiveProfiles ("test"). У вас не работает?
Compito

36
Если я создаю src/test/resources/application.propertiesфайл, src/main/resources/application.propertiesпри запуске тестов содержимое игнорируется.
ciastek 02

6
@ciastek Вы можете добавить application-test.propertiesдля тестов и переопределить только те свойства, которые вам нужны.
Advicer

3
@Advicer, который не обрабатывается, если свойства по умолчанию не указаны, spring.profiles.active=testкак указано в ответе.
OrangeDog

4
@OrangeDog - возможно, вы можете использовать профиль default, который активен по умолчанию. Таким образом, вы могли бы добавить такую ​​строку в test / resources / application-default.properties (если, конечно, у вас уже есть файл src / main / application-default.properties :-)
Joensson

16

Деларативный способ сделать это (на самом деле, небольшая поправка к исходному ответу @ Compito):

  1. Установить spring.profiles.active=testв test/resources/application-default.properties.
  2. Добавьте test/resources/application-test.propertiesдля тестов и переопределите только те свойства, которые вам нужны.

2
Означает ли это, что значение по умолчанию application.propertiesв пути к классам тоже анализируется, test/resources/application-default.propertiesа затем, поскольку обнаружен профиль "test", test/resources/application-test.propertiesанализируется? В противном случае это не решит проблему @ciastek, как указано в ответе @ Compito .
anddero

8

Если вы используете maven, вы можете добавить это в pom.xml:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <configuration>
                <argLine>-Dspring.profiles.active=test</argLine>
            </configuration>
        </plugin>
        ...

Затем maven должен запустить ваши интеграционные тесты (* IT.java) с помощью этого инструмента, а также IntelliJ запустится с активированным этим профилем, чтобы вы могли затем указать все свойства внутри

application-test.yml

и вам не нужны свойства "-default".


Сработало для меня, но мне пришлось добавить конфигурации в плагин surefire вместе с отказоустойчивым.
Mohammed

5

В моем случае у меня разные application.properties в зависимости от среды, например:

application.properties (base file)
application-dev.properties
application-qa.properties
application-prod.properties

а application.properties содержит свойство spring.profiles.active для выбора нужного файла.

Для своих интеграционных тестов я создал новый application-test.propertiesфайл внутри, test/resourcesи с @TestPropertySource({ "/application-test.properties" })аннотацией это файл, который отвечает за выбор application.properties, которые я хочу, в зависимости от моих потребностей для этих тестов


Вы должны использовать @ActiveProfiles, а не @TestPropertySource.
OrangeDog

Я думаю, что это не против использования @TestPropertiesSource. Это также способ загрузки конфигурации между конфигурацией теста профиля.
soyphea

5

Чтобы активировать "тестовый" профиль, напишите в build.gradle:

    test.doFirst {
        systemProperty 'spring.profiles.active', 'test'
        activeProfiles = 'test'
    }

4

Другой программный способ сделать это:

  import static org.springframework.core.env.AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME;

  @BeforeClass
  public static void setupTest() {
    System.setProperty(DEFAULT_PROFILES_PROPERTY_NAME, "test");
  }

Отлично работает.


4

Вы можете поместить свои свойства теста в src/test/resources/config/application.properties .

Свойства, определенные в этом файле, переопределят те, которые определены в src/main/resources/application.properties время тестирования.

Дополнительные сведения о том, почему это работает, можно найти в документации Spring Boots .


Здесь много хороших идей, которые пригодятся во многих случаях. IMHO @Matze ответ - самый краткий и простой ответ на этот вопрос, профили не нужны, не требуется изменение тестового кода ... Кроме того, ведение журнала более чистое (так что в моем случае это сбивает с толку, что Spring журналы с использованием диалекта: org.hibernate.dialect.PostgreSQL93Dialect когда мой тест, к счастью, использует вместо этого тестовую базу данных H2).
Раймонд Насиф,

1

Если вы просто хотите установить / использование профиля по умолчанию в момент создания сборки через Maven затем передать аргумент -Dspring.profiles.active=test Так же , как

mvn clean install -Dspring.profiles.active = dev


0

Добавьте spring.profiles.active=testsв свой файл application.properties, вы можете добавить несколько файлов свойств в свое приложение весенней загрузки, например application-stage.properties, application-prod.propertiesи т. Д. И вы можете указать в своем файле application.properties файл для ссылки, добавивspring.profiles.active=stage илиspring.profiles.active=prod

вы также можете передать профиль во время запуска приложения загрузки Spring, указав команду:

java -jar-Dspring.profiles.active=localbuild/libs/turtle-rnr-0.0.1-SNAPSHOT.jar

В соответствии с именем профиля выбирается файл свойств, в приведенном выше случае при передаче профиля localрассматривается application-local.propertiesфайл

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.