Spring 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是否也能正常运行。
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
}
谢谢您的任何建议!
答案 0 :(得分:1)
深入研究问题后,我得到了这个简单的解决方法。
@Sql(scripts = "/scripts/entity_test_clear.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
对于 scripts 参数,它必须是一个编译时间常数。您不能简单地从 application.properties 获取当前配置文件值并替换为运行正确的脚本名称。
通过ScriptUtils执行正确的脚本引入@After和@Before方法相当冗长,实际上对我不起作用(在脚本执行过程中发生了一些冻结)。
所以我所做的只是介绍一个带有单个常量的类:
/**
* 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 配置文件,以及2)将此常量更改为 mysql ;
这并不意味着是示例性的解决方案,只是一种可行的解决方法。
答案 1 :(得分:0)
您可以将@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();
}
}