[英]Not able to run Spring JUnit tests with second data source
I am using SpringJUnit4ClassRunner to run my integration tests. 我正在使用SpringJUnit4ClassRunner来运行集成测试。 I had to use two data sources in my Spring Boot REST web service because I want to use different database users for Liquibase and Application queries.
我必须在Spring Boot REST Web服务中使用两个数据源,因为我想对Liquibase和Application查询使用不同的数据库用户。 When I run the test, the second datasource is not getting created.
当我运行测试时,没有创建第二个数据源。
Following is my test code 以下是我的测试代码
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest
public class DomainServiceImplTest {
@Test
public void testCreateDomain() throws Exception {
}
}
Following is my datasource instantiation 以下是我的数据源实例化
@Configuration
@EnableTransactionManagement
public class DatabaseConfiguration {
private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);
@Inject
private Environment env;
@Autowired(required = false)
private MetricRegistry metricRegistry;
@Bean(destroyMethod = "close")
@Primary
public DataSource dataSource(DataSourceProperties dataSourceProperties, NileRegistrarProperties nileRegistrarProperties) {
log.debug("Configuring Datasource");
if (dataSourceProperties.getUrl() == null) {
log.error("Your database connection pool configuration is incorrect! The application" +
" cannot start. Please check your Spring profile, current profiles are: {}",
Arrays.toString(env.getActiveProfiles()));
throw new ApplicationContextException("Database connection pool is not configured correctly");
}
HikariConfig config = new HikariConfig();
config.setDriverClassName(dataSourceProperties.getDriverClassName());
config.setJdbcUrl(dataSourceProperties.getUrl());
if (dataSourceProperties.getUsername() != null) {
config.addDataSourceProperty("user", dataSourceProperties.getUsername());
} else {
config.addDataSourceProperty("user", ""); // HikariCP doesn't allow null user
}
if (dataSourceProperties.getPassword() != null) {
config.addDataSourceProperty("password", dataSourceProperties.getPassword());
} else {
config.addDataSourceProperty("password", ""); // HikariCP doesn't allow null password
}
//MySQL optimizations, see https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration
if ("com.mysql.jdbc.jdbc2.optional.MysqlDataSource".equals(dataSourceProperties.getDriverClassName())) {
config.addDataSourceProperty("cachePrepStmts", nileRegistrarProperties.getDatasource().isCachePrepStmts());
config.addDataSourceProperty("prepStmtCacheSize", nileRegistrarProperties.getDatasource().getPrepStmtCacheSize());
config.addDataSourceProperty("prepStmtCacheSqlLimit", nileRegistrarProperties.getDatasource().getPrepStmtCacheSqlLimit());
}
if (metricRegistry != null) {
config.setMetricRegistry(metricRegistry);
}
return new HikariDataSource(config);
}
@Bean(destroyMethod = "close")
public DataSource liquibaseDataSource(DataSourceProperties dataSourceProperties, LiquibaseProperties liquibaseProperties) {
log.debug("Configuring Liquibase Datasource");
if (dataSourceProperties.getUrl() == null) {
log.error("Your database connection pool configuration is incorrect! The application" +
" cannot start. Please check your Spring profile, current profiles are: {}",
Arrays.toString(env.getActiveProfiles()));
throw new ApplicationContextException("Database connection pool is not configured correctly");
}
HikariConfig config = new HikariConfig();
config.setDriverClassName(dataSourceProperties.getDriverClassName());
config.setJdbcUrl(dataSourceProperties.getUrl());
// Close all connections after liquibase operation is complete.
config.setMinimumIdle(0);
if (dataSourceProperties.getUsername() != null) {
config.addDataSourceProperty("user", liquibaseProperties.getUser());
} else {
config.addDataSourceProperty("user", ""); // HikariCP doesn't allow null user
}
if (dataSourceProperties.getPassword() != null) {
config.addDataSourceProperty("password", liquibaseProperties.getPassword());
} else {
config.addDataSourceProperty("password", ""); // HikariCP doesn't allow null password
}
return new HikariDataSource(config);
}
@Bean
public SpringLiquibase liquibase(@Qualifier("liquibaseDataSource") DataSource dataSource,
LiquibaseProperties liquibaseProperties) {
// Use liquibase.integration.spring.SpringLiquibase if you don't want Liquibase to start asynchronously
SpringLiquibase liquibase = new AsyncSpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog("classpath:config/liquibase/master.xml");
liquibase.setContexts(liquibaseProperties.getContexts());
liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema());
liquibase.setDropFirst(liquibaseProperties.isDropFirst());
liquibase.setShouldRun(liquibaseProperties.isEnabled());
log.debug("Configuring Liquibase");
return liquibase;
}
}
Following is the error message. 以下是错误消息。
Error creating bean with name 'dataSourceInitializer': Invocation of init method failed;
When I use single data source, everything is working is as expected. 当我使用单个数据源时,一切正常。
I am working on a similar project, where I have two datasources. 我正在一个类似的项目中,我有两个数据源。 Here is what I do,
datasource.primary.url=jdbc:mysql://localhost:3306/databaseName datasource.primary.username=username datasource.primary.password=password
这是我的工作,
datasource.primary.url=jdbc:mysql://localhost:3306/databaseName datasource.primary.username=username datasource.primary.password=password
Similarly for second datasource, datasource.secondary.url=jdbc:mysql://localhost:3306/databaseName datasource.secondary.username=username datasource.secondary.password=password
同样,对于第二个数据源,
datasource.secondary.url=jdbc:mysql://localhost:3306/databaseName datasource.secondary.username=username datasource.secondary.password=password
And in config class do just, 在config类中,
@Bean
@Primary
@ConfigurationProperties(prefix = "datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondaryDatasource")
@ConfigurationProperties(prefix = "datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
Wherever I need a datasource, I just autowire it like: 无论何时需要数据源,我都可以像这样自动布线:
public void setJdbcTemplate(@Qualifier("secondaryDatasource") DataSource dataSource) {
this.jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
Note: The datasource annotated @Primary
will be injected if @Qualifier
is not used while autowiring. 注意:如果在自动装配时未使用
@Qualifier
则将注入带注释的@Primary
数据源。
Testing is much simpler with this. 这样测试就简单得多。 If you want to use in memory database for testing (most common technique), just provide another set of properties, with url of the in memory database, which can be used by the test class
如果要使用内存数据库进行测试(最常用的技术),只需提供另一组属性,以及内存数据库的URL,测试类就可以使用该属性
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.