Spring Boot 测试:根据活动配置文件在测试中执行不同的 sql 脚本?

And*_*ver 5 java sql spring spring-boot

Spring Boot Test 是否可以根据活动配置文件设置 sql 脚本的条件执行?我的意思是,我对存储库进行了集成测试,并使用了一些 @sql 注释,例如:

@Sql(scripts = "/scripts/entity_test_clear.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
Run Code Online (Sandbox Code Playgroud)
  • 对于配置文件 h2,我想执行entity_test_clear.sql

  • 对于配置文件 mysql 我想执行entity_test_clear_mysql.sql

原因是我对这些数据库使用了不同的语法,尤其是这个:

  • ALTER TABLE organisation ALTER COLUMN org_id RESTART WITH 1;
  • ALTER TABLE organisation AUTO_INCREMENT = 1;

Mysql 不理解语法 #1,而 h2 不理解语法 #2(尽管设置了 mysql 模式,如 MODE=MYSQL)

默认情况下,我使用 h2 进行 IT 测试,但在一些罕见的情况下,我也想检查一切是否与 mysql 一起顺利运行。

PS我当然可以尝试一个直接的解决方案,@Profile并对h2和mysql的每个测试进行硬编码,但它与测试中的大量代码重复相结合,我想避免这种情况。

编辑: 测试用例如下所示:

@RunWith(SpringRunner.class)
@DataJpaTest
@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE)
public class EntityRepositoryTestIT {

    @Autowired
    private EntityRepository entityRepository;

@Test
@Sql(scripts = {"/scripts/entity_test_data.sql", "/scripts/entity_test_data_many.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/scripts/entity_test_clear.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void findTest() {
    Page<Entity> e = entityRepository.findBySomeDetails(1L, PageRequest.of(0, 20));
    Assert.assertEquals(3, e.getContent().size());
    Assert.assertEquals(1, e.getContent().get(0).getResources().size());
// more asserts

}
Run Code Online (Sandbox Code Playgroud)

感谢您的任何建议!

And*_*ver 5

经过对这个问题的深入研究后,我最终得到了这个简单的解决方法。

@Sql(scripts = "/scripts/entity_test_clear.sql", 
     executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
Run Code Online (Sandbox Code Playgroud)

对于scripts参数,它必须是编译时常量。您不能简单地从文件中获取当前配置文件值application.properties并替换它来运行正确的脚本名称。

执行正确脚本的介绍@After@Before方法ScriptUtils相当冗长,事实上,对我来说不起作用(在脚本执行过程中发生了一些冻结)。

所以我所做的只是引入一个具有单个常量的类:

/**
 * Constant holder for exceptionally database IT testing purposes
 * for switching between h2 and mysql
 */
public class ActiveProfile {
    /**
     * Current profile for database IT tests.
     * Make sure the value is equal to the value of
     * <i>spring.profiles.active</i> property from test application.properties
     */
    public static final String NOW = "h2";
}
Run Code Online (Sandbox Code Playgroud)

然后@sql行变成:

@Sql(scripts = "/scripts/test_data_clear_"+ ActiveProfile.NOW+".sql", 
     executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
Run Code Online (Sandbox Code Playgroud)

要使用另一个数据库进行测试(mysql)我只需要

  1. 更改文件spring.profiles.active=mysql中的当前配置文件application.properties
  2. 将此常数更改为mysql

这并不意味着它是典型的解决方案,而只是一种简单有效的解决方法。