问题
I am creating unittesting for spring boot application having multiple datasources. (Configuration is heavily inspired from this answer)
@Configuration public class DatasourceConfig { @Primary @Bean @ConfigurationProperties(prefix = "datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix = "datasource.primary.liquibase") public LiquibaseProperties primaryLiquibaseProperties() { return new LiquibaseProperties(); } @Bean public SpringLiquibase primaryLiquibase() { return springLiquibase(primaryDataSource(), primaryLiquibaseProperties()); } @Bean @ConfigurationProperties(prefix = "datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix = "datasource.secondary.liquibase") public LiquibaseProperties secondaryLiquibaseProperties() { return new LiquibaseProperties(); } @Bean public SpringLiquibase secondaryLiquibase() { return springLiquibase(secondaryDataSource(), secondaryLiquibaseProperties()); } private static SpringLiquibase springLiquibase(DataSource dataSource, LiquibaseProperties properties) { SpringLiquibase liquibase = new SpringLiquibase(); liquibase.setDataSource(dataSource); liquibase.setChangeLog(properties.getChangeLog()); liquibase.setContexts(properties.getContexts()); liquibase.setDefaultSchema(properties.getDefaultSchema()); liquibase.setDropFirst(properties.isDropFirst()); liquibase.setShouldRun(properties.isEnabled()); liquibase.setLabels(properties.getLabels()); liquibase.setChangeLogParameters(properties.getParameters()); liquibase.setRollbackFile(properties.getRollbackFile()); return liquibase; } ... }
and
datasource: primary: url: jdbc:mysql://localhost/primary username: username password: password liquibase: change-log: classpath:/db/changelog/db.primary.changelog-master.xml secondary: url: jdbc:mysql://localhost/secondary username: username password: password liquibase: change-log: classpath:/db/changelog/db.secondary.changelog-master.xml
The application is running properly.
The problem is unit testing is failing with this configuration. I have used h2
as embedded DB. Added h2 as test dependency and added h2 in datasource URL as well in application.yaml for testing.
application.yaml for testing
management:
endpoints.web.exposure.include: "*"
security.enabled: false
spring:
zipkin:
discoveryClientEnabled: false
sender:
type: kafka
#type: web
liquibase:
enabled: false
datasource:
url: "jdbc:h2:mem:testdb"
jdbc-url: "jdbc:h2:mem:testdb"
username: sa
password:
secondary-datasource:
url: "jdbc:h2:mem:testdb"
jdbc-url: "jdbc:h2:mem:testdb"
username: sa
password:
datasource:
primary-liquibase:
liquibase:
url: "jdbc:h2:mem:testdb"
username: sa
password:
secondary-liquibase:
liquibase:
url: "jdbc:h2:mem:testdb"
username: sa
password:
liquibase:
enable: false
Unit testing file
package com.foo.bar.car;
import com.foo.bar.car.utils.KSUIDGenerator;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureTestDatabase
// https://stackoverflow.com/a/58786742/1534925
//@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
//@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
class CarApplicationTests {
@Test
public void contextLoads() {
String h = "Hello World!";
Assertions.assertEquals(h, "Hello World!");
}
@Test
public void testKSUIDGeneration() {
Assertions.assertNotNull(KSUIDGenerator.generateKSUID());
}
}
I have created a repository to demonstrate this.
When I do gradlew clean check
it gives me following error
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [liquibase.integration.spring.SpringLiquibase]: Factory method 'primaryLiquibase' threw exception; nested exception is java.lang.IllegalArgumentException: No visible constructors in class org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean
Not sure what configuration change I am missing.
来源:https://stackoverflow.com/questions/61123061/tests-not-working-for-multiple-datasource-with-spring-boot-liquibase