Як встановити змінну середовища або властивість системи у весняних тестах?


93

Я хотів би написати кілька тестів, які перевіряють конфігурацію XML Spring розгорнутої WAR. На жаль, деякі компоненти вимагають встановлення деяких змінних середовища або властивостей системи. Як я можу встановити змінну середовища до ініціалізації спринкових компонентів, використовуючи зручний тестовий стиль з @ContextConfiguration?

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:whereever/context.xml")
public class TestWarSpringContext { ... }

Якщо я налаштовую контекст програми за допомогою анотацій, я не бачу гачка, де я можу щось зробити до ініціалізації контексту spring.

Відповіді:


127

Ви можете ініціалізувати властивість System у статичному ініціалізаторі:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:whereever/context.xml")
public class TestWarSpringContext {

    static {
        System.setProperty("myproperty", "foo");
    }

}

Статичний код ініціалізатора буде виконаний до ініціалізації контексту програми Spring.


14
Дурний я - добре, це спрацювало б Навіть краще: ймовірно, @BeforeClassметод встановлення властивості системи та @AfterClassметод його видалення також спрацював би, і приємно прибирав би за собою. (Однак не спробував.)
Ганс-Петер Стерр,

1
Спробував @BeforeClass - і він чудово працював для встановлення властивостей системи до того, як інші властивості були встановлені в тестовому екземплярі
wbdarby

Дякую за це. Статична річ не спрацювала, але невеликий метод з @BeforeClass спрацював!
Midhun Agnihotram

Цей механізм не працює, якщо змінюється властивість файлу конфігурації Log4j2. Здається, Spring в будь-якому випадку завантажується (і тому неправильно реєструється) перед тим статичним фрагментом коду.
lucasvc

86

Правильним способом зробити це, починаючи з Spring 4.1, є використання @TestPropertySourceанотації.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:whereever/context.xml")
@TestPropertySource(properties = {"myproperty = foo"})
public class TestWarSpringContext {
    ...    
}

Див. @TestPropertySource у весняних документах та Javadocs .


2
Ця анотація також підтримує шлях до файлу властивостей.
MigDus

2
Я міг змінити мітку Spring Cloud Config Client під час тестів, використовуючи@TestPropertySource(properties={"spring.cloud.config.label=feature/branch"})
Marcello de Sales

4
Гарна відповідь, але, на жаль, у мене не вийшло, використовуючи Spring 4.2.9, властивість завжди було порожньою. Працював лише статичний блок ... Працював для властивостей програми, але не для властивостей системи.
Грегор

Спочатку я побачив і спробував статичну версію (яка спрацювала), але ця Анотація ще чистіша і набагато краща (для мене, оскільки вона також працює як шарм).
BAERUS

3
Це надає Environmentвластивість, яка відрізняється від "змінної середовища".
OrangeDog

11

Можна також використовувати тестовий ApplicationContextInitializer для ініціалізації системної властивості:

public class TestApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>
{
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext)
    {
        System.setProperty("myproperty", "value");
    }
}

а потім налаштуйте його в тестовому класі на додаток до розташування файлів конфігураційного контексту Spring:

@ContextConfiguration(initializers = TestApplicationContextInitializer.class, locations = "classpath:whereever/context.xml", ...)
@RunWith(SpringJUnit4ClassRunner.class)
public class SomeTest
{
...
}

Таким чином можна уникнути дублювання коду, якщо для всіх модульних тестів слід встановити певну системну властивість.


Це також чудово працює з Spring Boot 2.x та Junit 5.x (використовуючи @SpringBootTestабо будь-яку з анотацій тестового нарізання )
Вім Деблау

11

Всі відповіді тут наразі говорять лише про властивості системи, які відрізняються від змінних середовища, які є більш складними для встановлення, особливо. для тестів. На щастя, для цього може бути використаний клас нижче, і документи класу мають добрі приклади

EnvironmentVariables.html

Швидкий приклад із документів, модифікованих для роботи з @SpringBootTest

@SpringBootTest
public class EnvironmentVariablesTest {
   @ClassRule
   public final EnvironmentVariables environmentVariables = new EnvironmentVariables().set("name", "value");

   @Test
   public void test() {
     assertEquals("value", System.getenv("name"));
   }
 }

Правила EnvironmentVariables є частиною сторонньої бібліотеки, використовує хакерське відображення для зміни кешованих значень середовища в пам'яті JVM і навіть не використовує фактичні змінні середовища. Отже, я не хотів би ним користуватися чи рекомендувати будь-кому це робити.
Крістіан

4

Якщо ви хочете, щоб ваші змінні були дійсними для всіх тестів, у вас може бути application.propertiesфайл у каталозі тестових ресурсів (за замовчуванням:), src/test/resourcesякий виглядатиме приблизно так:

MYPROPERTY=foo

Потім це буде завантажено та використано, якщо у вас немає визначень за допомогою @TestPropertySourceабо подібного методу - точний порядок завантаження властивостей можна знайти в розділі 24. Документація Spring. Зовнішня конфігурація .


2

Ви можете встановити властивості системи як аргументи віртуальної машини.

Якщо ваш проект - проект maven, ви можете виконати таку команду під час запуску тестового класу:

mvn test -Dapp.url="https://stackoverflow.com"

Тестовий клас:

public class AppTest  {
@Test
public void testUrl() {
    System.out.println(System.getProperty("app.url"));
    }
}

Якщо ви хочете запустити окремий тестовий клас або метод у eclipse, тоді:

1) Перейдіть до пункту Виконати -> Конфігурація запуску

2) Ліворуч виберіть свій тест в розділі Junit.

3) виконайте наступне:

введіть тут опис зображення


2

Для модульних тестів системна змінна ще не створюється, коли я роблю "чисту інсталяцію mvn", оскільки немає сервера, на якому запущена програма. Отже, щоб встановити властивості системи, мені потрібно це зробити у pom.xml. Подобається так:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.21.0</version>
    <configuration>
        <systemPropertyVariables>
            <propertyName>propertyValue</propertyName>
            <MY_ENV_VAR>newValue</MY_ENV_VAR>
            <ENV_TARGET>olqa</ENV_TARGET>
            <buildDirectory>${project.build.directory}</buildDirectory>
        </systemPropertyVariables>
    </configuration>
</plugin>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.