#java #spring
#java #spring
Вопрос:
У меня есть проект, который быстро расширяется и теперь имеет более ста компонентов. Для модульного тестирования у меня есть @Configuration
класс для замены заглушенных классов, таких как служба базы данных с ограниченной функциональностью:
@Configuration
public class SpringDevTestConfiguration {
@Bean
@Profile("unittest")
public DatabaseService databaseService() {
// this one is needed for the test
return new TestDatabaseServiceImpl();
}
@Bean
@Profile("unittest")
public RobotControlService robotControlService() {
// Why should I do this on every service?
return new RobotControlServiceImpl();
}
... etc.
Подавляющему большинству компонентов не нужны тестовые альтернативы, поэтому мы хотим, чтобы по умолчанию один, который существует и выбирается во время выполнения. Но всякий раз, когда в систему добавляется новый компонент, мы должны добавлять его во все @Configuration
классы, иначе мы получаем исключение « NoSuchBeanDefinitionException
: нет подходящего компонента типа …». Это слишком много шаблонного кода для возврата классов Impl и не позволяет нам создавать классы реализации, защищенные от пакетов (потому что класс конфигурации должен иметь возможность создавать их экземпляры).
Я попытался добавить @ComponentScan
в класс, но это приводит к BeanDefinitionOverrideException
. Если я разрешу переопределение компонента с:
spring.main.allow-bean-definition-overriding=true
… тогда я получаю NoUniqueBeanDefinitionException
из-за множества реализаций службы базы данных.
Я уверен, что я, должно быть, что-то упускаю. Как я могу создать короткий, простой @Configuration
класс, который создает экземпляры только тех тестовых реализаций, которые мне нужны для теста, а затем позволяет автоматически обнаруживать другие службы без их явного создания?
Комментарии:
1. Рассмотрите возможность использования Mockito вместо этого.
2. Спасибо, но я спрашиваю о том, как прекратить перечислять (сотни) не издевающихся служб.
3. Можете ли вы показать минимальный пример проекта? Хотя, вероятно, необходимо иметь некоторое дублирование компонентов, нетипично добавлять его ко «всем
@Configuration
классам». Обычно конфигурация вашего приложения выполняется таким образом, что в файлах конфигурации yml / xml можно переопределять только то, что отличается между профилями (dev, prod, test и т.д.). В этом случае, если у каждого отдельного компонента есть определенная тестовая реализация, ваша тестовая настройка, вероятно, не очень значима.4. Еще немного информации… Я вижу другие
@Configuration
аннотированные классы в системе только с одним-пятью@Bean
методами (некоторые издевались, некоторые нет). Но в данном случае это действительно интеграционный тест, который генерирует десятки тысяч тестов с использованием@TestFactory
(из JUnit 5) тысяч отдельных классов бизнес-логики. Поскольку они являются интеграционными тестами, создаваемыми динамически, им требуется большинство реальных сервисов, доступных при их запуске. Похоже, что у Spring нет способа легко использовать службы проверки компонентов по умолчанию.