Spring DbUnit检查自动生成id
我需要使用DbUnit执行集成测试。我已经创建了数据集(测试前后),并使用Spring DbUnit检查自动生成id,spring,hibernate,dbunit,Spring,Hibernate,Dbunit,我需要使用DbUnit执行集成测试。我已经创建了数据集(测试前后),并使用@DatabaseSetup和@ExpectedDatabase注释对它们进行了比较。在测试期间,创建了一个新的数据库行(它显示在测试后的数据集中,我使用@ExpectedDatabase注释指定)。问题是行id是自动生成的(我使用的是Hibernate),所以行id是永久更改的。因此,我的测试只通过一次,之后我需要在测试后数据集中更改id,但这不是我需要的。如果这个问题可以用DbUnit解决,您能为我推荐任何解决方案吗。
@DatabaseSetup
和@ExpectedDatabase
注释对它们进行了比较。在测试期间,创建了一个新的数据库行(它显示在测试后的数据集中,我使用@ExpectedDatabase
注释指定)。问题是行id是自动生成的(我使用的是Hibernate),所以行id是永久更改的。因此,我的测试只通过一次,之后我需要在测试后数据集中更改id,但这不是我需要的。如果这个问题可以用DbUnit解决,您能为我推荐任何解决方案吗。解决方案A:
使用分配的id策略并使用单独的查询来检索业务逻辑中的下一个值。因此,您可以在持久性测试中通过适当的数据库清理来分配一个已知的id。请注意,这仅在使用Oracle序列时有效
解决方案B:
如果我没有弄错的话,在org.dbunit.Assertion中有一些类似于assertEqualsIngoreColumns()的方法。因此,如果您不介意,可以忽略id断言。通常我会用一个非空的id检查来补偿。也许@ExpectedDatabase中有一些选项,但我不确定
解决方案C:
我想知道是否有更好的解决方案,因为解决方案a引入了一些性能开销,而解决方案B牺牲了一点测试覆盖率
顺便问一下,您使用的是什么版本的dbunit。我从未在2.4.9及以下版本中见过这些注释,它们看起来更易于使用。到目前为止,此解决方案一直在保护我的皮肤: 我实现了一个具有替换功能的AbstractDataSetLoader:
public class ReplacerDataSetLoader extends AbstractDataSetLoader {
private Map<String, Object> replacements = new ConcurrentHashMap<>();
@Override
protected IDataSet createDataSet(Resource resource) throws Exception {
FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
builder.setColumnSensing(true);
try (InputStream inputStream = resource.getInputStream()) {
return createReplacementDataSet(builder.build(inputStream));
}
}
/**
* prepare some replacements
* @param dataSet
* @return
*/
private ReplacementDataSet createReplacementDataSet(FlatXmlDataSet dataSet) {
ReplacementDataSet replacementDataSet = new ReplacementDataSet(dataSet);
//Configure the replacement dataset to replace '[null]' strings with null.
replacementDataSet.addReplacementObject("[null]", null);
replacementDataSet.addReplacementObject("[NULL]", null);
replacementDataSet.addReplacementObject("[TODAY]", new Date());
replacementDataSet.addReplacementObject("[NOW]", new Timestamp(System.currentTimeMillis()));
for (java.util.Map.Entry<String, Object> entry : replacements.entrySet()) {
replacementDataSet.addReplacementObject("["+entry.getKey()+"]", entry.getValue());
}
replacements.clear();
return replacementDataSet;
}
public void replace(String replacement, Object value){
replacements.put(replacement, value);
}
}
我预期的数据集需要一些替换emp1和emp2
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
<company.entity_group ID="15155" corporate_name="comp1"/>
<company.entity_group ID="15156" corporate_name="comp2"/>
<company.entity_group ID="[emp1]" corporate_name="comp3"/>
<company.entity_group ID="[emp2]" corporate_name="comp3"/>
<company.ref_entity ID="1" entity_group_id="[emp1]"/>
<company.ref_entity ID="2" entity_group_id="[emp2]"/>
</dataset>
使用DatabaseAssertionMode.NO\u STRICT,并从'expect.xml'中删除'id'列。
DBUnit将忽略此列。我遇到了类似的问题,您是否制定了解决方案?我忽略了id断言。参见解决方案B(下面的答案)。对于我的测试用例,这样的断言不是必需的。如何在注释中集成assertEqualsIngoreColumns()?顺便说一句,我还发现在数据源连接的数据库中使用内存中的数据库也是另一种选择,因为内存中的数据库在每次运行测试时都会进行初始化。
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
<company.entity_group ID="15155" corporate_name="comp1"/>
<company.entity_group ID="15156" corporate_name="comp2"/>
<company.entity_group ID="[emp1]" corporate_name="comp3"/>
<company.entity_group ID="[emp2]" corporate_name="comp3"/>
<company.ref_entity ID="1" entity_group_id="[emp1]"/>
<company.ref_entity ID="2" entity_group_id="[emp2]"/>
</dataset>