Тест весенней загрузки с множественной конфигурацией - PullRequest
0 голосов
/ 08 декабря 2018

В моем проекте Spring boot 2.1 у меня разные @Configuration s для разных тестов (ConfigurationA и ConfigurationB), которые находятся в разных пакетах.Обе конфигурации определяют один и тот же набор bean-компонентов, но по-разному (насмешливо и по-настоящему)

. Как мне известно о механизме Overlay , представленном в Spring Boot 2.1, я имеюустановите свойство: spring.main.allow-bean-definition-overriding=true.

Однако у меня есть тест с последующей настройкой следующей конфигурации и класса тестирования.Сначала в продуктивной части есть @Configuration (я использую Maven):

package com.stackoverflow;

@Configuration
public class ProdConfiguration{
...
}

Затем в ветке test есть общий тест @Configuration на том же уровне пакета:

package com.stackoverflow

@Configuration
public class TestConfiguration {
  @Bean
  public GameMap gameMap() {
    return Mockito.mock(GameMap.class);
  }
}

А в подпакете у меня есть еще один @Configuration:

package com.stackoverflow.impl;

@Configuration
public class RealMapTestConfiguration {
  @Bean
  public GameMap gameMap() {
    return new GameMap("testMap.json");
  }
}

И, конечно, меня беспокоит тест:

package com.stackoverflow.impl;

@ExtendWith(SpringExtension.class)
@SpringBootTest
@ContextConfiguration(classes={RealMapTestConfiguration.class, ProdConfiguration.class})
@ActiveProfiles("bug") // spring.main.allow-bean-definition-overriding=true
public class MapImageServiceIT {
  @Autowired
  private GameMap map;
} 

ОказываетсяОказалось, что введенный GameMap в мой тест является имитирующим экземпляром из TestConfiguration вместо реального из RealMapTestConfiguration.В моем тесте у меня была конфигурация ProdConfiguration и TestConfiguration, когда я хотел ProdConfiguration и RealMapTestConfiguration.Поскольку бины, определенные в ProdConfiguration и *TestConfiguration, отличаются, комбинация работает, но TestConfiguration и RealMapTestConfiguration определяют то же самое, что и ранее.Кажется, что TestConfiguration обнаружен компонентным сканированием, поскольку он находится в том же пакете, что и ProdConfiguration.У меня сложилось впечатление, что при переопределении bean-компонентов предпочтение будет отдаваться определению, которое ближе к тестовому классу.Однако, похоже, что это не так.

Итак, вот мои вопросы:

  1. При переопределении бобов, каков порядок?Какой бин переопределяет какой?
  2. Как получить правильный экземпляр в моем тесте (использование другого имени бина не вариант, так как на самом деле внедренный бин не используется непосредственно в тесте, а вслужба, используемая в тесте, и в ней нет спецификатора.)

Ответы [ 2 ]

0 голосов
/ 09 декабря 2018

Я думаю, что проблема здесь в том, что включение ContextConfiguration сводит на нет (часть) эффект @SpringBootTest.@SpringBootTest имеет эффект поиска @SpringBootConfiguration в вашем приложении (я полагаю, начиная с того же пакета).Однако, если применяется ContextConfiguration, то конфигурации загружаются оттуда.

Другой способ сказать, что: поскольку в вашем тесте ContextConfiguration, сканирование для классов @Configuration отключено, а TestConfiguration не загружен.

Я не думаю, что у меня есть полное представление о вашей конфигурации, поэтому я не могу порекомендовать здесь лучший метод, но быстрый способ исправить это - добавить TestConfiguration кваш ContextConfiguration в вашем тесте.Убедитесь, что вы добавили его последним, чтобы он переопределял определения bean-компонентов в двух других конфигурациях.

Другая вещь, с которой может работать, - это полное удаление @ContextConfiguration и разрешение SpringBootApplicationСканирование делает свое дело - вот где может применяться то, что вы сказали об определении бина, которое наиболее близко.

0 голосов
/ 09 декабря 2018

Я не использовал свойство spring.main.allow-bean-definition-overriding=true, но указание конкретной конфигурации в тестовом классе мне помогло как способ переключения между объектами в разных тестах.

Вы говорите ...

Оказывается, что внедренный GameMap в мой тест является поддельным экземпляром из TestConfiguration, а не реальным объектом из RealMapTestConfiguration.

Но RealMapTestConfiguration действительно возвращает макет

package com.stackoverflow.impl;

@Configuration
public class RealMapTestConfiguration {
  @Bean
  public GameMap gameMap() {
    return Mockito.mock(GameMap.class);
  }
}
...