How can I execute @Sql before @BeforeAll (JUnit5)

Viewed 3419

I have an integration test class with following scenario:

  • I want a sql script to be loaded as first thing. I use for this purpose the Spring @Sql annotation at class level

  • and then, I have a @BeforeAll (JUnit5) method i'd like to execute only once, after the @Sql has been executed.

My problem is that the content of @BeforeAll is been executed before the import of the @Sql script and not after.

Why is this so, and what can I do to reverse the order?

@SpringBootTest
@Transactional
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Sql(scripts={"classpath:data-postgreForDemoAndIt.sql"}, executionPhase = BEFORE_TEST_METHOD)
public class DatingManagerIT {

(...) 

  @BeforeAll
    public void init() {

        MockitoAnnotations.initMocks(this);

        Member memberDenise = memberDao.findByEmail("denise@yahoo.fr", Member.class).get();
        Member memberAnne = memberDao.findByEmail("anne@yahoo.fr", Member.class).get();
        Member memberJulien = memberDao.findByEmail("julien@yahoo.fr", Member.class).get();
        memberDao.delete(memberDenise);
        memberDao.delete(memberAnne);
        memberDao.delete(memberJulien);
        memberFactory.createSampleMembers();
    }
(...)
}
1 Answers

It might be an old question already but since there's no answer - here's my somewhat dirty take on it.

Inspired by the javadoc:

@BeforeEach methods from superclasses will be executed before @BeforeEach methods in subclasses.

I tried and found the following approach to work (the code has been adapted from my test-case):

  1. Create an abstract superclass with @Sql annotation like so:
@Sql(scripts={"classpath:data-postgreForDemoAndIt.sql"}, executionPhase = BEFORE_TEST_METHOD)
public abstract class AsbtractSqlBasedTest{}
  1. Extend it and convert the @BeforeAll to a @BeforeEach with a static flag on the class to ensure it only runs once, like so:
@SpringBootTest
@Transactional
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
BEFORE_TEST_METHOD)
public class DatingManagerIT extends AsbtractSqlBasedTest {

  private static boolean initDone=false;

  @BeforeEach
    public void init() {
        if (initDone) return;
        initDone = true;
    
        MockitoAnnotations.initMocks(this);

        Member memberDenise = memberDao.findByEmail("denise@yahoo.fr", Member.class).get();
        Member memberAnne = memberDao.findByEmail("anne@yahoo.fr", Member.class).get();
        Member memberJulien = memberDao.findByEmail("julien@yahoo.fr", Member.class).get();
        memberDao.delete(memberDenise);
        memberDao.delete(memberAnne);
        memberDao.delete(memberJulien);
        memberFactory.createSampleMembers();
    }
(...)
}
Related