在bean上使用@PostConstruct进行春季测试@SqlGroup

时间:2018-08-31 19:49:42

标签: java spring junit

在尝试使用 Spring 5,Junit4.11和JDK8进行集成测试之前,我尝试使用@SqlGroup执行一些SQL语句。

直到今天,一切都运转良好,当我在我的“ ConfigurationComponent” bean上添加了带有@PostConstruct批注的一些初始配置时。

@PostConstruct方法调用依赖数据库的bean时,测试失败,因为hiberante(因此数据库)找不到预加载的架构。

经过调查,我发现@SqlGroup中放入的语句将在ApplicationContext初始化之后执行,因此@PostConstruct在加载架构之前执行。

这是我的集成测试抽象类。

restored map: Map(y -> 2, x -> 1)

令人反感的豆子

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:application-context-test.xml" })
@Transactional
@Rollback(true)
@SqlGroup({
        @Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = {
                "classpath:db_config.sql",
                "classpath:consultas/setup_esquema_0.1.sql",
                "classpath:db_datos_iniciales.sql"}),
        @Sql(executionPhase = ExecutionPhase.AFTER_TEST_METHOD, scripts = "classpath:db_teardown.sql") })
public abstract class AbstractServiceTest {

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {

    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
    }

    @Before
    public abstract void setUp() throws Exception;

    @After
    public abstract void tearDown() throws Exception;

    public static Long randomId() {
        return new Long(Math.round(Math.random() * 1000));
    }

}

我找不到使用@SqlGroup解决此问题的方法。是否有解决方案,一种可以更改生命周期并首先执行sql语句的方法? 如您所见,我正在使用@Configuration public class ConfigurationComponent { @Autowired Resources resources; // resources are retrieved from database. @PostConstruct public void startUp() throws VariableGlobalInexistenteException { Config.environment = resources .getWsaaEnv(); Config.validation = resources .getWsaaEnvValidation(); } } , 这种情况下的显式配置,例如“ ExecutionPhase.BEFORE_SETUP”。


更新09-07-2018-看起来无法使用@Sql实现此目的:

  

@Sql和@PostConstruct的调用都由Spring处理   框架而不是Spring Boot。另外,我相信这是   设计。 @Sql的默认执行阶段是BEFORE_TEST_METHOD   (另一个选项是AFTER_TEST_METHOD)。应用程序上下文是   刷新,因此一次调用@PostConstruct   测试类(实际上,如果多个测试类   共享相同的配置),这会在单个测试之前发生   方法被调用。换句话说,您不能使用@Sql作为一种手段   为在@PostConstruct中进行的调用准备数据库。

Github @PostConstruct executed before @Sql

2 个答案:

答案 0 :(得分:1)

我设法找到了解决方法。如最新更新所述,无法使用@SqlGroup实现所需的行为。我不得不使用以下方法,即@BeforeClass和@AfterClass:

@BeforeClass
public static void setUpBeforeClass() throws Exception {

    DriverManagerDataSource dataSource = getDataSource();
    Connection conn = dataSource.getConnection();
    ScriptUtils.executeSqlScript(conn, new ClassPathResource("db_config.sql"));
    ScriptUtils.executeSqlScript(conn, new ClassPathResource("consultas/setup_schema"));
    ScriptUtils.executeSqlScript(conn, new ClassPathResource("db_init.sql"));
    JdbcUtils.closeConnection(conn);

}

@AfterClass
public static void tearDownAfterClass() throws Exception {
    Connection conn = getDataSource().getConnection();
    ScriptUtils.executeSqlScript(conn, new ClassPathResource(
            "db_teardown.sql"));
    JdbcUtils.closeConnection(conn);
}

private static DriverManagerDataSource getDataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setUrl(url);
    dataSource.setUsername(username);
    dataSource.setPassword(password);
    dataSource.setDriverClassName(driver);
    return dataSource;
}

所有@SqlGroup批注均已删除。这种方法非常干净,因为ScriptUtils不需要太多依赖项即可运行。

答案 1 :(得分:0)

另一种解决方法是实现CommandLineRunner。

@Component
public class ConfigurationInitRunner implements CommandLineRunner {

    @Autowired
    Resources resources; // resources are retrieved from database.

    @Override
    public void run(String... strings) throws Exception {
        Config.environment = resources.getWsaaEnv();
        Config.validation = resources.getWsaaEnvValidation();
    }
}