Spring的测试注释@Sql如何表现像@BeforeClass? [英] How can Spring's test annotation @Sql behave like @BeforeClass?

查看:221
本文介绍了Spring的测试注释@Sql如何表现像@BeforeClass?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何告诉@Sql注释对于该类仅运行一次,而不对于每个@Test方法仅运行一次?

How can I tell the @Sql annotation to run only once for the class, and not for each @Test method?

是否具有与@BeforeClass相同的行为?

Like having the same behaviour as @BeforeClass?

@org.springframework.test.context.jdbc.Sql(
     scripts = "classpath:schema-test.sql",
     executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD
)
public class TestClass {
      @Test
      public void test1() {
        //runs the @Sql script
      }

      @Test
      public void test2() {
        //runs the @Sql script again
      }
}

推荐答案

对于JUnit 5,直接 clean solution :

For JUnit 5, the straight forward clean solution:

@MyInMemoryDbConfig
//@Sql(value = {"/appconfig.sql", "/album.sql"}) -> code below is equivalent but at class level
class SomeServiceTest {
    @BeforeAll
    void setup(@Autowired DataSource dataSource) {
        try (Connection conn = dataSource.getConnection()) {
            // you'll have to make sure conn.autoCommit = true (default for e.g. H2)
            // e.g. url=jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1;MODE=MySQL
            ScriptUtils.executeSqlScript(conn, new ClassPathResource("appconfig.sql"));
            ScriptUtils.executeSqlScript(conn, new ClassPathResource("album.sql"));
        }
    }
    // your @Test methods follow ...

,但是当您的数据库连接未使用autoCommit = true配置时,则必须将所有内容包装在事务中:

but when your database connections are not configured with autoCommit = true you'll have to wrap all in a transaction:

@RootInMemoryDbConfig
@Slf4j
class SomeServiceTest {
    @BeforeAll
    void setup(@Autowired DataSource dataSource,
            @Autowired PlatformTransactionManager transactionManager) {
        new TransactionTemplate(transactionManager).execute((ts) -> {
            try (Connection conn = dataSource.getConnection()) {
                ScriptUtils.executeSqlScript(conn, new ClassPathResource("appconfig.sql"));
                ScriptUtils.executeSqlScript(conn, new ClassPathResource("album.sql"));
                // should work without manually commit but didn't for me (because of using AUTOCOMMIT=OFF)
                // I use url=jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1;MODE=MySQL;AUTOCOMMIT=OFF
                // same will happen with DataSourceInitializer & DatabasePopulator (at least with this setup)
                conn.commit();
            } catch (SQLException e) {
                SomeServiceTest.log.error(e.getMessage(), e);
            }
            return null;
        });
    }
    // your @Test methods follow ...

为什么清洁 解决方案?

因为根据

@Sql和@SqlConfig提供的配置选项是 等效于ScriptUtils和 ResourceDatabasePopulator,但是由 XML名称空间元素.

The configuration options provided by @Sql and @SqlConfig are equivalent to those supported by ScriptUtils and ResourceDatabasePopulator but are a superset of those provided by the XML namespace element.

奖金

您可以将此方法与其他@Sql声明混合使用.

You can mix this approach with other @Sql declarations.

这篇关于Spring的测试注释@Sql如何表现像@BeforeClass?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆