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

uelo1irk  于 2023-04-10  发布在  Java
关注(0)|答案(2)|浏览(141)

Sping Boot Test是否可以根据活动配置文件设置sql脚本的条件执行?我的意思是,我有一些@sql注解的存储库集成测试,如:

@Sql(scripts = "/scripts/entity_test_clear.sql", 
     executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
  • 对于配置文件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检查一切是否顺利。
P.S我当然可以用@Profile尝试一个直接的解决方案,并为h2Mysql的每个测试硬编码两个副本,但它与测试中的大量代码重复相结合,我想避免。

已编辑:

测试用例如下所示:

@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

}

谢谢您的任何建议!

c0vxltue

c0vxltue1#

在深入研究了这个问题之后,我最终得到了这个简单的解决方案。

@Sql(scripts = "/scripts/entity_test_clear.sql", 
     executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)

对于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";
}

然后@sql行变成:

@Sql(scripts = "/scripts/test_data_clear_"+ ActiveProfile.NOW+".sql", 
     executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)

要使用另一个数据库进行测试(mysql),我只需要
1.在application.properties文件中更改当前spring.profiles.active=mysql配置文件
1.将此常数更改为mysql;
这并不意味着是一个示范性的解决方案,只是一个简单的工作方法。

4si2a6ki

4si2a6ki2#

您可以使用@Profile注解与单独的类,每个类用于每个DMBS,将公共逻辑放在另一个类中以避免代码重复。您正在使用Spring,所以您可以通过以下内容获得它。

@Profile("mysql")
@Sql(scripts="... my mysql scripts...")
public class MySqlTests{
    
    @Autowired
    private CommonTestsLogic commonLogic;
    
    @Test
    public void mySqlTest1(){
       commonlogic.test1();
    }

}

@Profile("oracle")
@Sql(scripts="... my oracle scripts...")
public class MyOracleTests{
   
   @Autowired
   private CommonTestsLogic commonLogic;
   
   @Test
   public void myOracleTest1(){
       commonlogic.test1();
   }

}

相关问题