If I run dbunit with the following setup and request data via HTTP in an integration test, I didn't get any data because the database is empty. DBUnit writes data to the database, but it's empty when I request the data via HTTP.
This is my setup: Spring Boot 1.1.7 with spring-boot-starter-web (exclude tomcat), spring-boot-starter-jetty, spring-boot-starter-data-jpa, spring-boot-starter-test, liquibase-core, dbunit 2.5.0, spring-test-dbunit 1.1.0
Main Application Class:
@Configuration
@ComponentScan
@EnableAutoConfiguration
@RestController
@EnableTransactionManagement
@EnableJpaRepositories
Test configuration (application-test.yaml):
logging.level.org.springframework: DEBUG
logging.level.org.dbunit: DEBUG
spring.jpa.properties.hibernate.hbm2ddl.auto: update
spring.jpa.database: h2
spring.jpa.show-sql: true
// setting these properties to access the database via h2 console
spring.datasource.url: jdbc:h2:tcp://localhost/mem:my_db;DB_CLOSE_DELAY=-1;MVCC=true;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username: sa
spring.datasource.password: sa
spring.datasource.driverClassName: org.h2.Driver
spring.jpa.database-platform: org.hibernate.dialect.H2Dialect
liquibase.change-log: classpath:/db/changelog/db-master.xml
Integration test:
@ActiveProfiles("test")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = HDImageService.class)
@TestExecutionListeners({
DependencyInjectionTestExecutionListener.class,
DbUnitTestExecutionListener.class })
@WebAppConfiguration
@IntegrationTest("server.port:0")
@DatabaseSetup("/database_seed.xml")
@DatabaseTearDown(value = "/database_tear_down.xml", type = DatabaseOperation.DELETE_ALL)
// test
@Test
public void get_works() throws Exception {
// given
String url = host + port + "/my-resource/1";
// when
ResponseEntity<String> response = template.getForEntity(url, String.class);
// then
assertThat(response.getStatusCode(), is(HttpStatus.OK));
}
I could post everything else here, like the entities, repository, controller, ... but these components are working, because I already write in the test via the injected repository to the database and get it via HTTP. So the problem is the import via dbunit, which is not working... I already used dbunit successfully in an older projected, but not together with spring boot. Perhaps the execution listeners are working not similar with spring boot?
I debug threw the classes of dbunit and read all the debug log output, but I don't get it. DBUnit is using the spring boot created dataSource (the above configured), so it's the same database.
When starting the integration tests, the following is happen:
- liquibase creates the database schema based on the liquibase configuration (perhaps jpa already pushed the schema before?)
- DBUnit insert into the database (says the log output and debugging)
- Get 404 not found (I return a 404 when no entry was found in the database with the given ID)
Update:
I'm searching for an alternative to dbunit, but can't find any good solution. So how do you prepare your database for your integration tests? Actually I'm only need to import individuell data before every test or test if the data is persisted as expected.
Update:
I use the following options to connect to the h2 database:
DB_CLOSE_DELAY=-1;MVCC=true;DB_CLOSE_ON_EXIT=FALSE
When I removed the complete spring.datasource.* configuration spring is creating the datasource with standard values and start an in-memory h2 database server. This will be done without the options I mentioned and I get a org.hibernate.PessimisticLockException
because dbunit still locks the database table and the HTTP request which was send inside the test, has no access to the database table. This is because of the option MVCC=true;
which added higher concurrency, what is basically the problem, why no data is present: "Connections only 'see' committed data, and own changes". When accessing the database via the HTTP request, the data of dbunit is not present, because the data of dbunit is not committed for the spring connection...
So, does anyone know why the h2 (and also derby) database table(s) are locked by dbunit?