Сбой SpringBootTest после класса @Configuration: Ошибка при создании компонента с именем «источник данных»

#java #spring-boot #unit-testing

Вопрос:

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

 @Configuration
public class DBConfig {

@Value("${spring.datasource.username:}")
private String username;

@Value("${spring.datasource.url:}")
private String url;

@Bean
@DependsOn("passwordProvider")
public DataSource datasource(PasswordProvider passwordProvider) {
    return DataSourceBuilder
            .create()
            .url(url)
            .username(username)
            .password(new String(passwordProvider.getKeyByName("DB_PASSWORD").getKey()))
            .build();
}
 } 
 

Теперь все мои SpringbootTests неудачи с приведенным ниже исключением:

 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cloud.autoconfigure.RefreshAutoConfiguration$JpaInvokerConfiguration': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'datasource' defined in class path resource [com/example/configuration/DBConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'datasource' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:160)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:602)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:769)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:326)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:123)
 

Есть идеи, как это исправить ? Я не хочу предоставлять конфигурацию поставщика паролей в test.properties.

Комментарии:

1. Как говорит ваш собственный стек, Factory method 'datasource' threw exception; nested exception is java.lang.NullPointerException . Ваш компонент зависит от passwordProvider , но вы не показываете ни одного компонента с таким именем в своем @Configuration , так что может быть, вы его не инициализируете и поэтому указываете на нуль passwordProvider.getKeyByName(...) . В любом случае, невозможно сказать, что вы предлагаете в вопросе, мы можем только догадываться.

2. Компонент @MatteoNNZ passwordProvider создается путем предоставления конфигурации в файле свойств. Для тестовых занятий я не думаю, что мне следует это делать. Я просто хотел выполнить тестовые примеры без необходимости создавать источник данных.

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

4. Похоже, вы повторно объявляете встроенную конфигурацию. Просто позвольте DataSourceAutoConfiguration делать свою работу.

Ответ №1:

просто упомяните об этом в весеннем тесте загрузки, и он загрузит ваш класс конфигурации:

 @RunWith(SpringRunner.class)
@SpringBootTest(classes = {DBConfig.class})
public class SpringBootIntegrationTest {
    // ...
}