Можно ли параметризовать тест JUnit Jupiter с bean-компонентами из Spring ApplicationContext? - PullRequest
0 голосов
/ 26 июня 2019

Я хотел бы написать модульный тест, который выполняется для каждого бина Spring данного типа.Параметризованные тесты JUnit5 предлагают много возможностей, но я не знаю, как внедрить bean-компоненты в источник метода, поскольку это должен быть статический метод.

Есть ли способ определить параметры теста JUnit5 на основе контекста приложения Spring?

Ответы [ 2 ]

4 голосов
/ 26 июня 2019

Для начала заводской метод, настроенный с помощью @MethodSource, не обязательно должен быть static. Второе предложение в Руководстве пользователя объясняет это.

Методы фабрики в тестовом классе должны быть static, если тестовый класс не помечен @TestInstance(Lifecycle.PER_CLASS); тогда как фабричные методы во внешних классах всегда должны быть static.

Таким образом, если вы используете семантику @TestInstance(PER_CLASS), ваш фабричный метод @MethodSource может быть нестатичным и, следовательно, иметь доступ к ApplicationContext, введенному в экземпляр теста.

Вот пример, который демонстрирует это для bean-компонентов типа String с преднамеренным сбоем для bean-компонента bar.

import java.util.stream.Stream;

import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;

@SpringJUnitConfig
@TestInstance(PER_CLASS)
class SpringBeansParameterizedTests {

    @Autowired
    ApplicationContext applicationContext;

    @ParameterizedTest
    @MethodSource
    void stringBeans(String bean) {
        assertEquals(3, bean.length());
    }

    Stream<String> stringBeans() {
        return applicationContext.getBeansOfType(String.class).values().stream();
    }

    @Configuration
    static class Config {

        @Bean
        String foo() {
            return "foo";
        }

        @Bean
        String bar() {
            return "barf";
        }
    }
}

Если вы не хотите работать напрямую с ApplicationContext, вы можете упростить решение, введя непосредственно коллекцию всех таких bean-компонентов данного типа (String в этом примере), как показано ниже.

@SpringJUnitConfig
@TestInstance(PER_CLASS)
class SpringBeansParameterizedTests {

    @Autowired
    List<String> stringBeans;

    @ParameterizedTest
    @MethodSource
    void stringBeans(String bean) {
        assertEquals(3, bean.length());
    }

    Stream<String> stringBeans() {
        return this.stringBeans.stream();
    }

    @Configuration
    static class Config {

        @Bean
        String foo() {
            return "foo";
        }

        @Bean
        String bar() {
            return "barf";
        }
    }
}
0 голосов
/ 26 июня 2019

Использование @TestFactory может помочь.

На самом деле я наткнулся на пост, который делает довольно похожую (или ту же самую) вещь, что вы делаете на github .

Позвольте вашему Тесту пройти с SpringExtenion и использовать введенные Бины в качестве параметров для нашего Теста.

...