I'm writing integration tests for project and I want to merge all database migration scripts into schema.sql before Spring picks it up to populate the database. For this I use a small class that searches the project for sql files and merges them into one. I've created a Suite like so:
@RunWith(Suite.class)
@Suite.SuiteClasses({MyTests.class})
public class SuiteTest {
@BeforeClass
public static void setUp() throws IOException {
RunMigrations.mergeMigrations();//this one merges all sqls into one file, called schema.sql
}
}
Then, here's my test:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = App.class)
@ActiveProfiles(resolver = CustomActiveProfileResolver.class)
@ContextConfiguration(classes = App.class)
public class MyTests extends AbstractTransactionalJUnit4SpringContextTests {
@PostConstruct
public void before() {
mvc = MockMvcBuilders.webAppContextSetup(context).addFilter(springSecurityFilterChain).build();
}
@Test
@Transactional
public void Test1(){ //do stuff }
}
But this doesn't work as I thought it would. It looks like Spring tries to run schema.sql faster than I'm creating it and fails like this:
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [application]
If I just turn off my code that generates schema.sql and let Spring run with already created schema then all is good. But if I delete schema.sql and let my class to generate it, then it fails as described. I've tried to override run(RunNotifier notifier) method in SpringJUnit4ClassRunner and put my migration merger in there, before it calls super.run(notifier) method, but that still doesn't work. Is there a way to generate that schema.sql before Spring gets its hands on it?
P.S. I cannot use flyway for production environment. Perhaps it is possible using it just for tests?
UPD: After some experimenting, I've set this in test.yml:
spring.jpa.hibernate.ddl-auto: none
Now it loads context, performs one test which just gets Oauth2 token and fails with other tests that perform POST and GET requests because it cannot execute @sql annotations that put additional data before test methods. The database seems to be untouched, that is without any tables whatsoever.