Spring @Configuration被忽略

时间:2018-02-15 16:30:01

标签: java spring configuration spring-annotations dbunit

我将以下dbunit配置放在我所有测试类的父类中:

@Configuration
    public class MyDbUnitConfiguration {

        @Bean
        public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection() {
            DatabaseConfigBean bean = new DatabaseConfigBean();
            bean.setDatatypeFactory(new MySqlDataTypeFactory());
            bean.setMetadataHandler(new MySqlMetadataHandler());
            bean.setSkipOracleRecyclebinTables(true);
            bean.setCaseSensitiveTableNames(false);
            bean.setAllowEmptyFields(true);

            String testDbName = getTestDbName();
            LOG.debug("Test database name: " + testDbName);
            DataSource dataSource = new DataSource();
            dataSource.setUsername(USERNAME);
            dataSource.setPassword(PASSWORD);
            dataSource.setDriverClassName(JDBC_DRIVER);
            String url = "jdbc:mysql://localhost:3306/" + testDbName;
            dataSource.setUrl(url);

            DatabaseDataSourceConnectionFactoryBean dbConnectionFactory = new DatabaseDataSourceConnectionFactoryBean(
                    dataSource);
            dbConnectionFactory.setDatabaseConfig(bean);

            return dbConnectionFactory;
        }
    }

但是,当我运行任何子测试类时,会忽略此配置(没有打印日志,实际上没有设置属性)。

当我在子测试类上放置@Component注释时使用配置,但@Component只能使用一次,否则会打印一个异常:

org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'MyBaseTest' available: expected single matching bean but found 2: 
FooTest,BarTest

因此,我不能在每个子测试类上放置@Component注释。

如果将@Component注释放在父测试类上,则不会加载配置。

注: 每个子测试类使用不同的数据库,其名称使用方法getTestDbName()检索。我需要此信息来配置我的数据库连接。

在运行每个子测试类之前,获取配置的正确方法是什么?这是dbunit用于加载测试数据集的配置。

2 个答案:

答案 0 :(得分:0)

仔细阅读错误:

  

没有类型' MyBaseTest'的限定bean available:预期的单个匹配bean但找到2:   FooTest,BarTest

默认情况下,Spring按类型自动装配并找到两个名为FooTestBarTest的相同类型的bean。有两种直接的方法可以修复它:

  • 删除其中一个bean
  • @Qualifier("FooTest")注释与@Autowired注释一起使用,以定义哪个bean可供使用。

答案 1 :(得分:0)

注释@DbUnitConfiguration救了我。 我能够通过对它们添加以下注释来配置每个子测试类:

@Component
@DbUnitConfiguration(databaseConnection = { "myDbUnitConfigurationBean" })
public class FooTest extends MyBaseTest {

然后在每个子测试类中放置一个配置bean(以及指定bean的名称):

@Bean(name = "myDbUnitConfigurationBean")
public DatabaseDataSourceConnectionFactoryBean getDbUnitDatabaseConnection() {
    return createDbUnitDatabaseConnection(getTestDbName());
}

我还可以通过在父测试类中定义方法createDbUnitDatabaseConnection()来分解一些代码:

protected final DatabaseDataSourceConnectionFactoryBean createDbUnitDatabaseConnection(String testDbName) {
    DatabaseConfigBean bean = new DatabaseConfigBean();
    bean.setDatatypeFactory(new MySqlDataTypeFactory());
    bean.setMetadataHandler(new MySqlMetadataHandler());
    bean.setSkipOracleRecyclebinTables(true);
    bean.setCaseSensitiveTableNames(false);
    bean.setAllowEmptyFields(true);

    LOG.debug("Test database name: " + testDbName);
    DataSource dataSource = new DataSource();
    dataSource.setUsername(USERNAME);
    dataSource.setPassword(PASSWORD);
    dataSource.setDriverClassName(JDBC_DRIVER);
    String url = "jdbc:mysql://localhost:3306/" + testDbName;
    dataSource.setUrl(url);

    DatabaseDataSourceConnectionFactoryBean dbConnectionFactory = new DatabaseDataSourceConnectionFactoryBean(
            dataSource);
    dbConnectionFactory.setDatabaseConfig(bean);

    return dbConnectionFactory;
}

现在我的DbUnit配置被每个子测试类加载,这正是我想要的。