Spring的测试注释@Sql如何表现像@BeforeClass?

mem*_*und 7 java junit spring spring-test

我怎样才能使@Sql注释只对类运行一次,而不对每个@Test方法运行一次?

像有一样的行为@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
      }
}
Run Code Online (Sandbox Code Playgroud)

adr*_*rhc 14

对于 JUnit 5,直接的干净 解决方案

@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 ...
Run Code Online (Sandbox Code Playgroud)

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

@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 ...
Run Code Online (Sandbox Code Playgroud)

为什么要清洁 溶液

因为根据@SqlConfig 的脚本配置

和 提供的配置选项与@Sql@SqlConfig支持的配置选项等效,但是 XML 命名空间元素提供的ScriptUtils配置 ResourceDatabasePopulator选项的超集<jdbc:initialize-database/>

奖金

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

  • 谢谢!这是一个足够简单的解决方案......它对我来说效果很好! (2认同)