Reputation: 1475
There is an @Sql
annotation in spring which allows to execute sql code before and after the test method:
@Test
@Sql("init.sql")
@Sql(scripts = "clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void someTest()
{
}
However I have several test methods where I would like to provide the same clean environment like in the test above and I don't want to repeat for every test the same @Sql
annotation. How to do it once for all methods? For example:
// JPA and Spring other test annotations
@Sql("init.sql")
@Sql(scripts = "clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public class TestClass
{
// init.sql executed before every test, clean.sql executed after every test
}
Upvotes: 6
Views: 10796
Reputation: 10716
If my understanding is correct, you want to execute an init script to put the DB in a certain state, and then ensure the DB is back to that state before each test method, right?
The simplest solution is to use @Transactional
, then. By default, Spring Boot will automatically roll back the test transaction of a @Transactional
-annotated test, thus resetting the DB to the original state.
There are two downsides one should consider, though:
@Transactional
means there will exist a transaction spanning the entire execution of the test method which the tested service methods will typically join. Hence, the test itself cannot be relied upon to verify the correctess of transactional boundaries in the production code (LazyInitializationException
s may be covered by this 'outer' transacion, for example) @After
public void flushContext() {
if (TransactionSynchronizationManager.isActualTransactionActive()) {
entityManager.flush();
}
}
Upvotes: 0
Reputation: 1475
Indeed when you place @Sql
on the class
, sql scripts will be executed before and after every test defined in that class, more specifically before @Before
and after @After
methods. So,
// JPA and Spring other test annotations
@Sql("init.sql")
@Sql(scripts = "clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public class TestClass
{
// init.sql executed before every test, clean.sql executed after every test
}
is going to work according to the @Sql
definition:
@Target({ElementType.TYPE, ElementType.METHOD})
/// other annotations
public @interface Sql {
//
}
Upvotes: 8