【问题标题】:Spring boot test wrong configuration classesSpring Boot 测试错误的配置类
【发布时间】:2018-12-03 16:39:43
【问题描述】:

我正在尝试使用 Spring Boot 2.0.1 测试我的存储库层,但是当我运行我的测试类时,Spring 尝试实例化一个不是来自测试包的 Config 类。

这里是测试代码:

TestConfig.class

@Configuration
@Import(value = {TestDatabaseConfig.class})
@Profile("local")
public class TestConfig {

}

TestDatabaseConfig.class

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "logEntityManagerFactory",
        transactionManagerRef = "logTransactionManager",
        basePackages = { "it.xxx.yyy.repository.log" })
@EntityScan(basePackages = {"it.xxx.yyy.model.log", "it.xxx.yyy.common"})
@Profile("local")
public class TestDatabaseConfig {

@Bean("logDataSourceProperties")
public DataSourceProperties logDataSourceProperties() {
    return new DataSourceProperties();
}


@Bean(name = "logDataSource")
public DataSource dataSource(@Qualifier("logDataSourceProperties") DataSourceProperties properties) {
    return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.H2)
            .addScript("classpath:schema.sql")
            .build();
}

@Bean(name = "logEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean logEntityManagerFactory(EntityManagerFactoryBuilder builder,
                                                                      @Qualifier("logDataSource") DataSource logDataSource) {
    return builder.dataSource(logDataSource)
            .packages("it.xxx.model.log")
            .persistenceUnit("log")
            .build();
}

@Bean(name = "logTransactionManager")
public PlatformTransactionManager logTransactionManager(@Qualifier("logEntityManagerFactory")EntityManagerFactory logEntityManagerFactory) {
    return new JpaTransactionManager(logEntityManagerFactory);
}

}

当我运行这个类时

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("local")
public class LogRepositoryTest {

    @Autowired
    private ResultLogRepository resultLogRepository;

    @Test
    public void init(){
    }
}

上面写着:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'kafkaProducer': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'kafka.topic.operation' in value "${kafka.topic.operation}"
[...]
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'kafka.topic.operation' in value "${kafka.topic.operation}"

但我不明白为什么它会从我的主包(上面有 @Configuration 注释)中调出我的 KafkaProducer.class。

【问题讨论】:

    标签: spring spring-boot testing junit apache-kafka


    【解决方案1】:

    在您的 LogRepositoryTest 测试类中,您应该指出应该考虑的备用测试配置类,在您的情况下,我认为应该是 TestConfig

    来自 Spring Boot documentation:

    如果您熟悉 Spring 测试框架,您可能习惯使用 @ContextConfiguration(classes=…​) 来指定要加载哪个 Spring @Configuration。或者,您可能经常在测试中使用嵌套的 @Configuration 类。

    所以用@ContextConfiguration(classes = {TestConfig.class})注释LogRepositoryTest

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @ActiveProfiles("local")
    @ContextConfiguration(classes = {TestConfig.class})
    public class LogRepositoryTest {
    
        @Autowired
        private ResultLogRepository resultLogRepository;
    
        @Test
        public void init(){
        }
    }
    

    更新

    同时注释你的配置类:

    @EnableAutoConfiguration
    

    类似:

    @Configuration
    @EnableAutoConfiguration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "logEntityManagerFactory",
            transactionManagerRef = "logTransactionManager",
            basePackages = { "it.xxx.yyy.repository.log" })
    @EntityScan(basePackages = {"it.xxx.yyy.model.log", "it.xxx.yyy.common"})
    @Profile("local")
    public class TestDatabaseConfig {
    //...
    }
    

    更新 2

    对于错误:

    原因:org.springframework.beans.factory.NoUniqueBeanDefinitionException:没有“org.springframework.boot.autoconfigure.jdbc.DataSourceProperties”类型的合格bean可用:预期单个匹配bean但找到2:logDataSourceProperties,spring.datasource- org.springframework.boot.autoconfigure.jdbc.DataSourceProperties

    彻底删除方法:

    @Bean("logDataSourceProperties")
    public DataSourceProperties logDataSourceProperties() {
        return new DataSourceProperties();
    }
    

    并更改您的:

    @Bean(name = "logDataSource")
    public DataSource dataSource(@Qualifier("logDataSourceProperties") DataSourceProperties properties) {
     // ...
    }
    

    到:

    @Bean(name = "logDataSource")
    public DataSource dataSource(DataSourceProperties properties) {
     // ...
    }
    

    【讨论】:

    • 好的,我确实像你说的那样,现在我得到了这个异常: 原因:org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.orm.jpa .EntityManagerFactoryBuilder' 可用:预计至少有 1 个符合自动装配候选资格的 bean。依赖注释:{}
    • 这可能意味着在您的TestDatabaseConfig 中创建EntityManagerFactoryBuilder bean 的logEntityManagerFactory() 未加载。您可以调试您的项目以查看在那里放置断点是否有效?否则尝试将@ContextConfiguration(classes = {TestConfig.class}) 更改为@ContextConfiguration(classes = {TestDatabaseConfig.class})
    • 我在那里添加了一个断点,但我不知道失败的原因......它在没有更多信息的情况下打印 NoSuchBeanDefinitionException 等,即使在 DEBUG 中也是如此。
    • 所以..它不会停止到断点?只是为了确保,将断点放在以下行:return builder.dataSource(logDataSource)
    • 它是否在TestDatabaseConfig 内的任何断点处停止?这意味着根本看不到您的配置类,这很奇怪,因为它是在 @ContextConfiguration(classes = {TestDatabaseConfig.class}) 中声明的
    猜你喜欢
    • 1970-01-01
    • 2021-02-16
    • 2021-05-22
    • 1970-01-01
    • 2017-09-06
    • 2019-04-15
    • 2020-11-01
    • 2018-06-27
    • 2021-12-23
    相关资源
    最近更新 更多