Подтвердить что ты не робот

Как исключить классы AutoConfiguration в тегах Spring Boot JUnit?

Я пробовал:

@RunWith(SpringJUnit4ClassRunner.class)
@EnableAutoConfiguration(exclude=CrshAutoConfiguration.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class LikeControllerTest {

Однако CRaSSHD все еще запускается. Хотя в настоящее время это не навредит тесту, я бы хотел отключить ненужные модули во время модульного тестирования, чтобы ускорить работу, а также избежать возможных конфликтов.

4b9b3361

Ответ 1

Лучшие ответы не указывают на еще более простое и гибкое решение.

просто поместите

@TestPropertySource(properties=
{"spring.autoconfigure.exclude=comma.seperated.ClassNames,com.example.FooAutoConfiguration"})
@SpringBootTest
public class MySpringTest {...}

аннотации над вашим тестовым классом. Это означает, что другие тесты не затрагиваются особым случаем текущего теста. Если есть конфигурация, влияющая на большинство ваших тестов, рассмотрите возможность использования профиля пружины вместо этого, как подсказывает текущий верхний ответ.

Спасибо @skirsch за поддержку, чтобы я перешел от комментария к ответу.

Ответ 2

Еще один простой способ исключить классы автоматической конфигурации,

Добавьте приведенную ниже конфигурацию к вашему файлу application.yml,

---
spring:
  profiles: test
  autoconfigure.exclude: org.springframework.boot.autoconfigure.session.SessionAutoConfiguration

Ответ 3

У меня был аналогичный вариант использования, когда я хотел протестировать изолированный репозиторий Spring Boot, изолированный (в моем случае без Spring автоконфигурации безопасности, который не прошел мой тест). @SpringApplicationConfiguration использует SpringApplicationContextLoader и имеет JavaDoc с указанием

Может использоваться для тестирования не веб-функций (например, уровня репозитория) или запустите полностью сконфигурированный встроенный контейнер сервлета.

Однако, как и я, я не мог понять, как вы планируете настраивать тест только для проверки уровня репозитория, используя точку входа в главную конфигурацию, то есть используя ваш подход @SpringApplicationConfiguration(classes = Application.class).

Мое решение состояло в том, чтобы создать совершенно новый контекст приложения, исключительный для тестирования. Таким образом, в src/test/java у меня есть два файла в подпакетах с именем repo

  • RepoIntegrationTest.java
  • TestRepoConfig.java

где RepoIntegrationTest.java имеет

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestRepoConfig.class)
public class RepoIntegrationTest {

и TestRepoConfig.java имеет

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
public class TestRepoConfig {

Это избавило меня от неприятностей, но было бы очень полезно, если бы кто-либо из команды загрузки Spring мог предоставить альтернативное рекомендованное решение

Ответ 4

У меня была аналогичная проблема, но я пришел к другому решению, которое может помочь другим. Я использовал Spring Profiles для разделения классов конфигурации тестирования и приложений.

  • Создайте класс TestConfig с определенным профилем и исключите любую конфигурацию приложения из требуемого здесь компонента.

  • В вашем тестовом классе установите профиль в соответствии с TestConfig и включите его с помощью аннотации @ContextConfiguration.

Например:

конфигурации:

@Profile("test")
@Configuration
@EnableWebMvc
@ComponentScan(
    basePackages="your.base.package",
    excludeFilters = {
            @Filter(type = ASSIGNABLE_TYPE,
                    value = {
                            ExcludedAppConfig1.class,
                            ExcludedAppConfig2.class
            })
    })
public class TestConfig { ...}

Тест:

@ActiveProfiles("test")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class)
@WebAppConfiguration
public class SomeTest{ ... }

Ответ 5

Я думаю, что использование аннотации @EnableAutoConfiguration в тестовом классе не будет работать, если вы используете @SpringApplicationConfiguration для загрузки класса Application. Дело в том, что у вас уже есть аннотация @EnableAutoConfiguration в классе Application, которая не исключает CrshAutoConfiguration. Spring использует эту аннотацию вместо той, что находится в вашем тестовом классе, для автоматической настройки вашего beans.

Я думаю, что лучше всего использовать другой контекст приложения для своих тестов и исключить CrshAutoConfiguration в этом классе.

Я сделал несколько тестов, и кажется, что @EnableAutoConfiguration в тестовом классе полностью игнорируется, если вы используете аннотацию @SpringApplicationConfiguration и SpringJUnit4ClassRunner.

Ответ 6

В новой аннотации @SpringBootTest я принял этот ответ и модифицировал его для использования профилей с классом конфигурации @SpringBootApplication. Аннотация @Profile необходима, чтобы этот класс был выбран только в ходе конкретных тестов интеграции, которые нуждаются в этом, так как другие тестовые конфигурации выполняют разное сканирование компонентов.

Вот класс конфигурации:

@Profile("specific-profile")
@SpringBootApplication(scanBasePackages={"com.myco.package1", "com.myco.package2"})
public class SpecificTestConfig {

}

Затем класс тестирования ссылается на этот класс конфигурации:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = { SpecificTestConfig.class })
@ActiveProfiles({"specific-profile"})
public class MyTest {

}

Ответ 8

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

Вместо использования @SpringBootApplication используйте все три аннотации, которые он содержит, и назначьте имя @Configuration

@Configuration("myApp")
@EnableAutoConfiguration
@ComponentScan
public class MyApp { .. }

В вашем тестовом классе определите конфигурацию с точно таким же именем:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
// ugly hack how to exclude main configuration
@Configuration("myApp")
@SpringApplicationConfiguration(classes = MyTest.class)
public class MyTest { ... }

Это должно помочь. Было бы неплохо иметь более эффективный способ, чтобы отключить автоматическое сканирование для аннотаций конфигурации...

Ответ 9

Я тоже боролся с этим и нашел простой шаблон, чтобы изолировать тестовый контекст после беглого чтения @ComponentScan docs.

/**
     * Тип-безопасная альтернатива {@link #basePackages} для указания пакетов
     * для сканирования аннотированных компонентов. Будет проверен пакет каждого указанного класса.
     * Рассмотрите возможность создания специального класса или интерфейса маркера no-op в каждом пакете
     * , который не имеет никакой цели, кроме ссылки на этот атрибут.
     */
    Class<?>[] basePackageClasses() default {};

  • Создайте пакет для тестов spring, ("com.example.test").
  • Создайте интерфейс маркера в пакете как квалификатор контекста.
  • Укажите ссылку интерфейса маркера в качестве параметра в basePackageClasses.

Пример


IsolatedTest.java

package com.example.test;

@RunWith(SpringJUnit4ClassRunner.class)
@ComponentScan(basePackageClasses = {TestDomain.class})
@SpringApplicationConfiguration(classes = IsolatedTest.Config.class)
public class IsolatedTest {

     String expected = "Read the documentation on @ComponentScan";
     String actual = "Too lazy when I can just search on Stack Overflow.";

      @Test
      public void testSomething() throws Exception {
          assertEquals(expected, actual);
      }

      @ComponentScan(basePackageClasses = {TestDomain.class})
      public static class Config {
      public static void main(String[] args) {
          SpringApplication.run(Config.class, args);
      }
    }
}

...

TestDomain.java

package com.example.test;

public interface TestDomain {
//noop marker
}

Ответ 10

Если у вас возникла проблема с Spring Boot 1.4.x и выше, вы можете использовать @OverrideAutoConfiguration(enabled=true) для решения проблемы.

Подобно тому, что было задано/ответили здесь fooobar.com/questions/156616/...

Ответ 11

Если проблема заключается в том, что ваша SpringBootApplication/Configuration, которую вы вводите, является компонентом, сканирующим пакет, в котором находятся ваши тестовые конфигурации, вы можете фактически удалить аннотацию @Configuration из тестовых конфигураций и по-прежнему использовать их в аннотациях @SpringBootTest. Например, если у вас есть класс Application, который является вашей основной конфигурацией, и класс TestConfiguration, который является конфигурацией для определенных, но не всех тестов, вы можете настроить свои классы следующим образом:

@Import(Application.class) //or the specific configurations you want
//(Optional) Other Annotations that will not trigger an autowire
public class TestConfiguration {
    //your custom test configuration
}

И тогда вы можете настроить свои тесты одним из двух способов:

  1. При штатной конфигурации:

    @SpringBootTest(classes = {Application.class}) //won't component scan your configuration because it doesn't have an autowire-able annotation
    //Other annotations here
    public class TestThatUsesNormalApplication {
        //my test code
    }
    
  2. С тестовой пользовательской конфигурацией теста:

    @SpringBootTest(classes = {TestConfiguration.class}) //this still works!
    //Other annotations here
    public class TestThatUsesCustomTestConfiguration {
        //my test code
    }
    

Ответ 12

Я боролся с подобной проблемой в течение одного дня... Мой сценарий:

У меня есть приложение SpringBoot, и я использую applicationContext.xml в scr/main/resources для настройки всех моих Spring Bean. Для тестирования (интеграционного тестирования) я использую другое applicationContext.xml в test/resources и все работает так, как я ожидал: Spring/SpringBoot переопределяет applicationContext.xml из scr/main/resources и использует тот для Testing, который содержит настроенные bean-компоненты для тестирования.

Тем не менее, только для одного UnitTest я хотел еще одну настройку для applicationContext.xml, используемого в тестировании, просто для этого теста я хотел использовать несколько бобов mockito, чтобы я мог mock и verify, и вот тут началась моя однодневная головная боль!

Проблема в том, что Spring/SpringBoot не переопределяет applicationContext.xml из scr/main/resources ТОЛЬКО ЕСЛИ файл из test/resources то же имя. Я часами пытался использовать что-то вроде:

@RunWith(SpringJUnit4ClassRunner.class)
@OverrideAutoConfiguration(enabled=true)
@ContextConfiguration({"classpath:applicationContext-test.xml"})

это не сработало, Spring сначала загружал бины из applicationContext.xml в scr/main/resources

Мое решение основано на ответах здесь @myroch и @Stuart:

  1. Определите основную конфигурацию приложения:

    @Configuration @ImportResource({"classpath:applicationContext.xml"}) public class MainAppConfig { }

это используется в приложении

@SpringBootApplication
@Import(MainAppConfig.class)
public class SuppressionMain implements CommandLineRunner
  1. Определите TestConfiguration для Test, где вы хотите исключить основную конфигурацию

    @ComponentScan (basePackages = "com.mypackage", excludeFilters = {@ComponentScan.Filter(type = ASSIGNABLE_TYPE, value = {MainAppConfig.class})}) @EnableAutoConfiguration открытый класс TestConfig {}

При этом для этого теста Spring не будет загружать applicationContext.xml и будет загружать только пользовательскую конфигурацию, специфичную для этого теста.