I am using Liquibase in my Spring web application. I have a group of objects with hundreds of tests for the REST API in integration tests for each object such as User, Account, Invoice, License, etc. All my integration tests pass when I run around the class, but many of them fail when shared gradle test. Most likely, there is a collision of data between the tests, and I'm not interested in wasting time on fixing data cleaning at the moment. I prefer to drop the database and context after each class. I decided that I could use it @DirtiesContextin the class, and so I annotated it with a test.
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class, SecurityConfiguration.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext
public class InvoiceResourceIntTest {
I see that after adding annotation, the web application context is launched for each class, but when Liquibase is initialized, the requests do not start because the checksum matches. Since this is a database in memory, I expected the DB to be destroyed along with the Spring context, but this does not happen.
I also installed jpa hibernate ddl-auto in create-drop, but that didn't help. The next option that I am considering, instead mem, write h2db to a file and delete this file in @BeforeClass of my test integration file files. I prefer to automatically drop db in memory instead of controlling it in the test, but I want to try here as the last option. Thanks for the help.
Update:
I updated the test as shown below.
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class, SecurityConfiguration.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = "spring.datasource.name=AccountResource")
@DirtiesContext
public class AccountResourceIntTest {
. , , Liquibase .
app .yml
spring:
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:myApp;DB_CLOSE_DELAY=-1
name:
username:
password:
jpa:
database-platform: com.neustar.registry.le.domain.util.FixedH2Dialect
database: H2
open-in-view: false
show_sql: true
hibernate:
ddl-auto: create-drop
naming-strategy: org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy
properties:
hibernate.cache.use_second_level_cache: false
hibernate.cache.use_query_cache: false
hibernate.generate_statistics: true
hibernate.hbm2ddl.auto: validate
JHipster 2.x, . . . AppProperties - ( Spring).
@Configuration
public class DatabaseConfiguration {
private static final int LIQUIBASE_POOL_INIT_SIZE = 1;
private static final int LIQUIBASE_POOL_MAX_ACTIVE = 1;
private static final int LIQUIBASE_POOL_MAX_IDLE = 0;
private static final int LIQUIBASE_POOL_MIN_IDLE = 0;
private static final Logger LOG = LoggerFactory.getLogger(DatabaseConfiguration.class);
@Bean(destroyMethod = "close")
@ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)
@Primary
public DataSource dataSource(final DataSourceProperties dataSourceProperties,
final AppProperties appProperties) {
LOG.info("Configuring Datasource with url: {}, user: {}",
dataSourceProperties.getUrl(), dataSourceProperties.getUsername());
if (dataSourceProperties.getUrl() == null) {
LOG.error("Your Liquibase configuration is incorrect, please specify database URL!");
throw new ApplicationContextException("Data source is not configured correctly, please specify URL");
}
if (dataSourceProperties.getUsername() == null) {
LOG.error("Your Liquibase configuration is incorrect, please specify database user!");
throw new ApplicationContextException(
"Data source is not configured correctly, please specify database user");
}
if (dataSourceProperties.getPassword() == null) {
LOG.error("Your Liquibase configuration is incorrect, please specify database password!");
throw new ApplicationContextException(
"Data source is not configured correctly, "
+ "please specify database password");
}
PoolProperties config = new PoolProperties();
config.setDriverClassName(dataSourceProperties.getDriverClassName());
config.setUrl(dataSourceProperties.getUrl());
config.setUsername(dataSourceProperties.getUsername());
config.setPassword(dataSourceProperties.getPassword());
config.setInitialSize(appProperties.getDatasource().getInitialSize());
config.setMaxActive(appProperties.getDatasource().getMaxActive());
config.setTestOnBorrow(appProperties.getDatasource().isTestOnBorrow());
config.setValidationQuery(appProperties.getDatasource().getValidationQuery());
org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource(config);
LOG.info("Data source is created: {}", dataSource);
return dataSource;
}
@Bean(destroyMethod = "close")
@ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)
public DataSource liquibaseDataSource(final DataSourceProperties dataSourceProperties,
final LiquibaseProperties liquibaseProperties, final AppProperties appProperties) {
LOG.info("Configuring Liquibase Datasource with url: {}, user: {}",
dataSourceProperties.getUrl(), liquibaseProperties.getUser());
if (dataSourceProperties.getDriverClassName() != null
&& dataSourceProperties.getDriverClassName().startsWith("org.h2.")) {
return dataSource(dataSourceProperties, appProperties);
}
if (dataSourceProperties.getUrl() == null) {
LOG.error("Your Liquibase configuration is incorrect, please specify database URL!");
throw new ApplicationContextException("Liquibase is not configured correctly, please specify URL");
}
if (liquibaseProperties.getUser() == null) {
LOG.error("Your Liquibase configuration is incorrect, please specify database user!");
throw new ApplicationContextException(
"Liquibase is not configured correctly, please specify database user");
}
if (liquibaseProperties.getPassword() == null) {
LOG.error("Your Liquibase configuration is incorrect, please specify database password!");
throw new ApplicationContextException(
"Liquibase is not configured correctly, please specify database password");
}
PoolProperties config = new PoolProperties();
config.setDriverClassName(dataSourceProperties.getDriverClassName());
config.setUrl(dataSourceProperties.getUrl());
config.setUsername(liquibaseProperties.getUser());
config.setPassword(liquibaseProperties.getPassword());
config.setInitialSize(LIQUIBASE_POOL_INIT_SIZE);
config.setMaxActive(LIQUIBASE_POOL_MAX_ACTIVE);
config.setMaxIdle(LIQUIBASE_POOL_MAX_IDLE);
config.setMinIdle(LIQUIBASE_POOL_MIN_IDLE);
org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource(config);
LOG.info("Liquibase data source is created: {}", dataSource);
return dataSource;
}
@Bean
public SpringLiquibase liquibase(@Qualifier("liquibaseDataSource") final DataSource dataSource,
final DataSourceProperties dataSourceProperties, final LiquibaseProperties liquibaseProperties) {
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());
return liquibase;
}
}