在春季测试中,@Test方法之前,如何只填充一次数据库?

2022-09-02 01:18:06

我用 junit4 测试 spring 服务层的下一个问题是:如何在所有@Test方法之前调用只填充一次数据库的脚本:我想在所有@Tests之前执行一次:

JdbcTestUtils.executeSqlScript(jdbcTemplate(), new FileSystemResource(
"src/main/resources/sql/mysql/javahelp-insert.sql"), false);

我试图在我的GenericServiceTest类(由测试类扩展)上使用@PostConstruct。事实证明,每次@Test方法之前都会调用@PostConstruct。有趣的是,甚至在 GenericServiceTest @Autowired注释的方法也会在每个@Test方法之前调用。

我不想在每个测试类之前填充数据库,而只在春季测试启动时填充一次。

如何在使用弹簧测试框架和junit4的所有@Test方法之前仅执行上述方法一次?

谢谢!


答案 1

基于 Alfredos 答案,这是一种无需调用嵌入式数据库的默认脚本即可注入数据库信息的方法。例如,当您想要自动构建DDL时,这可能很有用 - 至少在测试中。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"/applicationContext.xml"})
public class TestClass {

    @Autowired
    private ApplicationContext ctx;

    private JdbcTemplate template;

    @Autowired
    public void setDataSource(DataSource dataSource) {
       template = new JdbcTemplate(dataSource);
    }

    private static boolean isInitialized = false;

    @Before
    public void runOnce() {
        if (isInitialized) return;
        System.out.println("Initializing database");

        String script = "classpath:script.sql"; 
        Resource resource = ctx.getResource(script);
        JdbcTestUtils.executeSqlScript(template, resource, true);            
        isInitialized = true;
    }
}

这样,该方法将调用一次,并且对于测试运行仅调用一次。如果创建实例字段(非静态),则将在每次测试之前调用该方法。这样,如有必要,您可以在每次测试运行之前删除/重新填充表。runOnce()isInitialized

请注意,这仍然是一个相当快速和肮脏的解决方案,处理数据库的明智方法是按照Ralph的答案。


答案 2

使用弹簧嵌入式数据库支持

<jdbc:embedded-database id="dataSource">
    <jdbc:script location="classpath:myScript.sql"/>
    <jdbc:script location="classpath:otherScript.sql"/>
</jdbc:embedded-database>

或弹簧初始化数据库支持

<jdbc:initialize-database data-source="dataSource">
    <jdbc:script location="classpath:myScript.sql"/>
    <jdbc:script location="classpath:otherScript.sql"/>
</jdbc:initialize-database>

@See http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/jdbc.html#jdbc-embedded-database-support


推荐