I am running a JUnit integration test with an in-memory H2 database configured like so:
@Bean
public DataSource dataSource() {
try {
SimpleDriverDataSource simpleDriverDataSource = new SimpleDriverDataSource();
simpleDriverDataSource.setDriverClass((Class<? extends Driver>) ClassUtils.forName("org.h2.Driver", this.getClass().getClassLoader()));
simpleDriverDataSource.setUrl("jdbc:h2:file:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false;MVCC=true;FILE_LOCK=NO;mv_store=false");
simpleDriverDataSource.setUsername("sa");
simpleDriverDataSource.setPassword("");
return simpleDriverDataSource;
} catch(ClassNotFoundException e) {
throw new IllegalStateException(e.getMessage());
}
}
The test makes a call to a service method. This service method uses an executor service to fork the processing. Before the call to the service class, the test method inserts some data into the database, and this data can be read using the service (via JPA repository calls) up until the task is submitted to the executor service. However, when the task is run, it is unable to read the data that was persisted previously.
How can I make the forked thread see the persisted data?
Note: This is only failing for the Unit test, it is working fine at runtime.
4.1 concurrent-junitConcurrent-junit library helps the users to test the methods for multi threading. It will create threads for testing methods. By default, number of threads created by this library is 4, but we can set the desired number of threads.
Testing a multithreaded application is more difficult than testing a single-threaded application because defects are often timing-related and more difficult to reproduce. Existing code often requires significant re-architecting to take advantage of multithreading and multicontexting.
Starting with JUnit 4, tests can be run in parallel to gain speed for larger suites. The problem was concurrent test execution was not fully supported by the Spring TestContext Framework prior to Spring 5. In this quick article, we'll show how to use Spring 5 to run our tests in Spring projects concurrently.
Assuming that your test is @Transactional
, what you see is the expected behaviour as you (usually) don't want the changes made by a test to be visible to other tests/threads, and possibly, rolled back at the end of the test.
A simple way to work around this problem is to annotate the @Test
method like this
@Test
@Transactional(propagation = Propagation.NEVER)
public void testYourLogics() { /* ... */ }
I've been able to reproduce tour behaviour without the propagation = Propagation.NEVER
and to see it solved with it.
Please note that you will have to restore the database to a clean state manually after running the test, or the changes made by that test, will be visible to the other tests
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With