DBUnit,使用带注释配置的DTD

时间:2014-04-24 16:30:49

标签: java spring hibernate junit dbunit

我遇到了一个我无法解决的dbUnit测试问题。有一个数据结构具有由jpa注释定义的父子关系:

/**
 * Parent account
 */
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "parentAccountId", insertable = false, updatable = false)
private Account parentAccount;

/**
 * Subordinated accounts
 */
@OneToMany(mappedBy="parentAccount")
@JsonIgnore
private Set<Account> childAccounts = new HashSet<Account>();

我有一个抽象类,在执行junit测试之前在数据库中加载数据集,该类具有以下注释:

@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class })
@DatabaseSetup("classpath:db-test-script.xml")
@DatabaseTearDown(type=DatabaseOperation.DELETE_ALL, value = { "classpath:db-test-    script.xml" })

哪个很好但不适合我之前提到的类。数据集中的数据结构如下所示:

<referralAccount id="2" code="CODE2" />
<referralAccount id="1" code="CODE" parentAccountId="2"/>

但是我在日志中找到的问题如下:

FlatXmlProducer:316 - 表格第2行的额外列(parentAccountId)(全局行号为5)。这些列将被忽略。     请将额外的列添加到第1行,或使用DTD确保填充这些列的值,或为FlatXmlProducer指定“columnSensing = true”。     有关详细信息,请参阅常见问题解答。

问题是,有没有办法通过注释指定dtd或columnSensing?我不想实现setUp方法,如果我可以避免它,因为注释似乎是一个简单的方法来处理这个。

谢谢!

3 个答案:

答案 0 :(得分:1)

如果您使用的是DBUnit 2.3.0或更高版本,则可以使用dbunit javadoc中描述的ColumnSensing属性:

  

请注意DbUnit可能会认为某个表在第一个列时会遗漏某些列   该表的行有一个或多个空值。你可以做其中一个   以下事情要避免这种情况:

     

从DBUnit 2.3.0开始,有一个名为&#34; column sensing&#34;   它基本上将整个XML读入缓冲区并动态调用   在出现时添加新列。它可以如下所示使用   以下示例:

  // since dbunit 2.4.7
   FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
   builder.setInputSource(new File("src/xml/flatXmlTableTest.xml"));
   builder.setColumnSensing(true);
   IDataSet dataSet = builder.build();

   // or dbunit release <= 2.4.6:
   boolean enableColumnSensing = true;
   IDataSet dataSet = new FlatXmlDataSet(
            new File("src/xml/flatXmlTableTest.xml"), false, enableColumnSensing);

因此,如果您使用的是spring,则可以创建一个类,如:

public class ColumnDetectorXmlDataSetLoader extends FlatXmlDataSetLoader {
@Override
protected IDataSet createDataSet(Resource resource) throws Exception {
FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
builder.setColumnSensing(true);
InputStream inputStream = resource.getInputStream();
try {
return builder.build(inputStream);
} finally {
inputStream.close();
}
}
}

然后在你的junit测试中:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/spring-context.xml" })
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DbUnitTestExecutionListener.class })
@DatabaseSetup("my-dataset.xml")
@DatabaseTearDown("my-dataset.xml")
// Reference to the ColumnDetectorXmlDataSetLoader
@DbUnitConfiguration(dataSetLoader = ColumnDetectorXmlDataSetLoader.class)
public class MyTestTest {

}

在此

答案 1 :(得分:1)

使用dbunit 2.5.1版

使用了这个:

InputStream inputStream = ClassNameTest.class.getResourceAsStream(name);
assertNotNull("file " + name + " not found in classpath", inputStream);
FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
builder.setColumnSensing(true);
return builder.build(inputStream);

答案 2 :(得分:0)

我之前遇到过同样的问题。有3个解决方案,我应用了前者:

  1. 在Flatxml中,每个第一行都应包含您要为给定表使用/测试的所有列。 (我没有找到任何方法在spring + dbunit中通过注释指定列感应),在你的情况下交换行。

  2. 使用DTD(不记得为什么我在那个时候丢弃了这个选项),你在数据集xml文件的开头指定一个DTD,即:<!DOCTYPE dataset SYSTEM "dataset.dtd">(参见下面的格式)

  3. (头痛方式)定义您自己的注释或删除注释和回退到经典的DbUnit / java,您可以完全控制列感应等事项。
  4. 数据集 DTD 具有以下格式(示例):

    <!ELEMENT dataset (
        ACCOUNT*)>
    <!ELEMENT ACCOUNT EMPTY>
    <!ATTLIST ACCOUNT
        USER_ID CDATA #REQUIRED
        ACCOUNT_BALANCE CDATA #REQUIRED
    >