简体   繁体   中英

Spring @Configuration is ignored

I put the following dbunit configuration inside the parent class of all my test classes:

@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;
        }
    }

However, this configuration gets ignored (no logs printed and properties actually not set) when I run any child test class.

The configuration is used when I put a @Component annotation on a child test class , but @Component can be used only once, elsewise an exception is printed:

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

Thus I cannot put a @Component annotation on every child test class.

If the @Component annotation is put on parent test class, configuration is not loaded.

Remark: every child test class uses a different database, whose name is retrieved using method getTestDbName() . I need this information to configure my database connection.

What would be the right way to get the configuration loaded before every child test class is run? This is the configuration that dbunit will use to load the dataset of the tests.

Read the error carefully:

No qualifying bean of type 'MyBaseTest' available: expected single matching bean but found 2: FooTest,BarTest

Spring autowires by type by default and found two beans of the same type named FooTest and BarTest There are two straightforward ways to fix it:

  • Remove one of the beans
  • Use the @Qualifier("FooTest") annotation with the @Autowired annotation to define which bean is a candidate for use.

Annotation @DbUnitConfiguration saved me. I was able to configure every child test class by putting the following annotations on them:

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

and then putting a configuration bean (and specifying the name of the bean ) in every child test class:

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

I could also factorize some code by defining the method createDbUnitDatabaseConnection() in the parent test class:

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;
}

Now my DbUnit configuration is loaded by every child test class and that's just what I wanted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM