DbUnit高级应用与优化技巧
立即解锁
发布时间: 2025-08-18 02:07:13 阅读量: 2 订阅数: 6 

### DbUnit 高级应用与优化技巧
#### 1. DbUnit 日志配置
在使用 DbUnit 时,有时运行 `testNULL()` 方法会失败且没有任何警告,这可能是因为 DbUnit 日志功能被禁用了。由于没有专门的 API 或配置文件来显式启用日志,需要配置 SLF4J。
- **已有日志框架**:若项目已使用如 log4j 或 Java 的 `java.util.logging` 等日志框架,可找到对应的 SLF4J 提供程序,将其 JAR 文件(如 `sl4j-log4j12.jar`)添加到类路径。
- **无日志框架**:若项目未使用任何日志框架,最简单的方法是添加 `sl4j-simple.jar`。该提供程序会将信息消息发送到 `System.out`,将警告和错误发送到 `System.err`,并忽略其他日志级别(如调试和跟踪)。
添加 `sl4j-simple.jar` 到类路径并再次运行测试用例,会得到类似如下警告:
```plaintext
474 [main] WARN org.dbunit.dataset.xml.FlatXmlProducer - Extra columns on
➥line 2. Those columns will be ignored.
474 [main] WARN org.dbunit.dataset.xml.FlatXmlProducer - Please add the
➥extra columns to line 1, or use a DTD to make sure the value of those
➥columns are populated or specify 'columnSensing=true' for your
➥FlatXmlProducer.
474 [main] WARN org.dbunit.dataset.xml.FlatXmlProducer - See FAQ for more
➥details.
```
当遇到类似 DbUnit 错误或使用问题时,可尝试启用较低的日志级别(如调试或跟踪),DbUnit 会输出大量调试信息,有助于解决问题。
#### 2. 从现有数据库数据创建数据集
之前的示例是从头开始创建数据集 XML 文件,这在纯 TDD 中是理想情况,但很多时候需要从数据库中已有的数据创建这些文件。
- **复杂项目场景**:在大型项目中,数据库开发由 DBA 团队负责,QA 团队维护包含测试数据的数据库实例。Java 代码和测试用例需要处理复杂场景,从头创建数据集不切实际且容易出错,可利用现有数据创建初始文件,再去除测试用例不需要的数据。
- **重现测试用例中的问题**:即使项目较简单,也可能遇到难以在测试用例中重现的错误。例如,用户访问 Web 应用程序,执行一些插入和更新操作后,页面显示的表格数据不正确。此时,可手动重现这些步骤,将相关数据库内容导出到数据集,然后在测试用例中仅重现出错的方法调用。
导出数据集的基本步骤如下:
1. 创建包含要导出数据的数据集对象,例如使用 `DatabaseConnection.createDataset()` 导出整个数据库,或使用 `QueryDataSet` 缩小数据范围。
2. 调用数据集格式类的静态方法(如 `FlatXmlDataSet`)。
示例代码如下:
```java
IDataSet fullDataSet = dbunitConnection.createDataSet();
FileOutputStream xmlStream = new FileOutputStream("full-database.xml");
FlatXmlDataSet.write(fullDataSet, xmlStream);
```
同样,也可生成数据集的 DTD:
```java
FileOutputStream dtdStream = new FileOutputStream("full-database.dtd");
FlatDtdDataSet.write(fullDataSet, dtdStream);
```
这种简单方法大多时候可行,但存在一个缺点:数据集中的表创建没有特定顺序。若一个表与另一个表有外键约束,且生成顺序错误,将数据集插入数据库时很可能失败。解决方法是使用 `FilteredDataSet` 包装数据集,并使用 `DatabaseSequenceFilter` 确保表按正确顺序返回:
```java
IDataSet fullDataSet = dbunitConnection.createDataSet();
ITableFilter filter = new DatabaseSequenceFilter(dbunitConnection);
FilteredDataSet filteredDatSet = new FilteredDataSet(filter, fullDataSet);
FileOutputStream xmlStream = new FileOutputStream("full-database.xml");
FlatXmlDataSet.write(filteredDatSet, xmlStream);
```
#### 3. DbUnit 与模板设计模式
从更高层面看,之前的示例遵循相同的工作流程:
1. 使用数据集 XML 文件准备数据库。
2. 开发测试用的 Java 代码。
3. (可选)将数据库状态与另一个数据集文件进行比较。
只有步骤 2 针对每个测试是特定的,步骤 1 和 3 除了 XML 文件位置外,对所有测试都是相同的。可使用模板设计模式进一步提高代码复用性。
以下是使用模板设计模式的示例代码:
```java
public class UserDaoJdbcImplTemplatePatternTest extends AbstractDbUnitTestCase {
protected interface TemplateWorker {
long getId();
void doIt() throws Exception;
String getSetupDataSet();
String getAssertDataSet();
}
protected void runTemplateTest(TemplateWorker worker) throws Exception {
IDataSet setupDataSet = getReplacedDataSet(worker.getSetupDataSet(), worker.getId() );
DatabaseOperation.CLEAN_INSERT.execute(dbunitConnection, setupDataSet);
worker.doIt();
String comparisonDataSetName = worker.getAssertDataSet();
if ( comparisonDataSetName != null ) {
IDataSet expectedDataSet = getReplacedDataSet(comparisonDataSetName, worker.getId());
IDataSet actualDataSet = dbunitConnection.createDataSet();
Assertion.assertEquals( expectedDataSet, actualDataSet );
}
}
@Test
public void testGetUserById() throws Exception {
final long id = 42; // value here does not matter
TemplateWorker worker = new TemplateWorker() {
public void doIt() throws Exception {
User user = dao.getUserById(id);
assertUser( user );
}
public String getSetupDataSet() { return "/user-token.xml"; }
public String getAssertDataSet() { return null; }
public long getId() { return id; }
};
runTemplateTest(worker);
}
@Test
public void
```
0
0
复制全文
相关推荐









