I have integration tests that are executed on top on inmemory database. The signature of each test looks more or less like this:
@RunWith(SpringRunner.class)
@SpringBootTest
@Sql("/clean-data-in-all-tables.sql")
public class SomeTest {
@Test
public void shouldDoSomehting() {}
}
During test-context initialization the DB schema is recreated by Hibernate:
spring:
jpa:
hibernate:
ddl-auto: create-drop
I expect sql script to be executed after initialization of context and after db schema generation. However in some cases clean-data-in-all-tables.sql
is executed before schema generation and it fails because it expects tables which were not yet created.
I have more than 500 tests written in the way I explained and they all were working well until I added few more similar tests.
Tests fail when I execute them together via Gradle or IntelliJ. Note the failed tests are not the tests which were recently added. This are the old tests totally unrelated to the ones I added. What is also strange is that the failed tests work well if I run them one by one through IntelliJ.
It looks like a bug of spring-boot however I still try to find a way to workaround it. At the same time I tried numerous of things to solve the issue however none of them was helpfull.
Please share your ideas on what could help and what could be wrong with my code.
UPDATE:
Found the workaround: changing the spring.jpa.hibernate.ddl-auto
from create-drop
to create
solves the problem.
But the question is still open what is the reason of such strange behaviour?
@SpringBootTest This annotation works by creating the ApplicationContext used in our tests through SpringApplication. It starts the embedded server, creates a web environment and then enables @Test methods to do integration testing. By default, @SpringBootTest does not start a server.
Again, very similar to the @DataJpaTest and the @DataMongoTest annotations, to perform classic Spring MVC tests, we apply the @WebMvcTest annotation alongside the @RunWith(SpringRunner. class) annotation. Keep in mind that the effects of this annotation only apply to the MVC infrastructure.
Spring Boot provides a @SpringBootTest annotation, which can be used as an alternative to the standard spring-test @ContextConfiguration annotation when you need Spring Boot features. The annotation works by creating the ApplicationContext used in your tests through SpringApplication .
One possible solution (I'm not sure if you are open for using DBUnit) can be:
1) Create Abstract Repository Integration Test:
@TestExecutionListeners({DbUnitTestExecutionListener.class})
@SpringApplicationConfiguration(classes = Application.class)
@DirtiesContext
public abstract class AbstractRepositoryIT extends AbstractTransactionalJUnit4SpringContextTests {
}
2) Create "real" integration test:
@DatabaseSetup(SomeEntityRepositoryIT.DATASET)
@DatabaseTearDown(type = DatabaseOperation.DELETE_ALL, value = {"dataset.xml})
public class SomeEntityRepositoryIT extends AbstractRepositoryIT {
...
}
In file dataset.xml you can set up initial state for your tests etc... More can be found here
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