我正在尝试设置我的单元测试环境以使用DbUnit。
我遇到了一些问题,因为我试图控制的表没有主键。我得到了org.dbunit.dataset.NoPrimaryKeyException
。
我已按照http://dbunit.wikidot.com/noprimarykeytable中的步骤操作,但我如何使用:
connection.getConfig().setProperty("http://www.dbunit.org/properties/primaryKeyFilter", new MyPrimaryKeyFilter("A1"));
我的每张桌子?
例如,我有以下数据库:
CREATE TABLE `NO_PK1` (
`A1` int(11) NOT NULL,
`A2` varchar(50) default NULL
);
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<NO_PK1 A1="1" A2="Test1" />
<NO_PK1 A1="2" A2="Test2" />
<NO_PK1 A1="3" />
</dataset>
CREATE TABLE `NO_PK2` (
`B1` int(11) NOT NULL,
`B2` varchar(50) default NULL
);
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<NO_PK2 B1="1" B2="Test1" />
<NO_PK2 B1="2" B2="Test2" />
<NO_PK2 B1="3" />
</dataset>
CREATE TABLE `NO_PK3` (
`C1` int(11) NOT NULL,
`C2` varchar(50) default NULL
);
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<NO_PK3 C1="1" C2="Test1" />
<NO_PK3 C1="2" C2="Test2" />
<NO_PK3 C1="3" />
</dataset>
如何在此实例中重写connection.getConfig().setProperty("http://www.dbunit.org/properties/primaryKeyFilter", new MyPrimaryKeyFilter("A1"));
?
非常感谢您的任何建议。
答案 0 :(得分:6)
您需要确保MyPrimaryKeyFilter处理架构中的所有表。在示例中,只有一个表,因此提供的简单过滤器类工作正常。在您的情况下,我可能会更改该类以获取包含表格的地图 - &gt; pk列名映射:
class MyPrimaryKeyFilter implements IColumnFilter {
private Map<String, String> pseudoKey = null;
MyPrimaryKeyFilter(Map<String, String> pseudoKey) {
this.pseudoKey = pseudoKey;
}
public boolean accept(String tableName, Column column) {
return column.getColumnName().equalsIgnoreCase(pseudoKey.get(tableName));
}
}
然后使用{NO_PK1 - &gt;设置地图A1},{NO_PK2 - &gt; B1}和{NO_PK3 - &gt; C1}条目。
答案 1 :(得分:3)
我遇到同样的问题并在这些博客中找到了解决方案:
所有博客作者均来自http://dbunit.wikidot.com/noprimarykeytable
此代码显示了检查ID的不同策略:
public static IDatabaseConnection getConnection(DataSource ds) throws Exception {
Connection con = ds.getConnection();
final DatabaseMetaData dbMetaData = con.getMetaData();
DatabaseConnection dbUnitCon = new DatabaseConnection(con, dbMetaData.getUserName().toUpperCase());
DatabaseConfig dbUnitConfig = dbUnitCon.getConfig();
dbUnitConfig.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new Oracle10DataTypeFactory());
dbUnitConfig.setProperty(DatabaseConfig.FEATURE_SKIP_ORACLE_RECYCLEBIN_TABLES, Boolean.TRUE);
dbUnitConfig.setProperty(DatabaseConfig.PROPERTY_PRIMARY_KEY_FILTER, new IColumnFilter() {
Map<String, List<String>> tablePrimaryKeyMap = new HashMap<>();
{
tablePrimaryKeyMap.put("CLIENT", Arrays.asList(new String[]{"FIRST_NAME", "MIDDLE_NAME", "LAST_NAME"}));
// ...
}
@Override
public boolean accept(String tableName, Column column) {
if ((tableName.startsWith("DATA_") || tableName.startsWith("PAYMENT_"))
&& ("COMPANY".equalsIgnoreCase(tableName) || "FILIAL".equalsIgnoreCase(tableName)
|| "BRANCH".equalsIgnoreCase(tableName) || "CASTOMER".equalsIgnoreCase(tableName)
|| "XDATE".equalsIgnoreCase(tableName)))
return true;
if (tablePrimaryKeyMap.containsKey(tableName))
return tablePrimaryKeyMap.get(tableName).contains(column.getColumnName());
else if ("id".equalsIgnoreCase(column.getColumnName())) {
return true;
}
try {
ResultSet rs = dbMetaData.getPrimaryKeys(null, null, tableName);
while (rs.next()) {
rs.getString("COLUMN_NAME");
if (rs.getString("COLUMN_NAME").equalsIgnoreCase(column.getColumnName())) {
return true;
}
}
} catch (SQLException ex) {
Logger.getLogger(DistributionControllerDbTest.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
});
return dbUnitCon;
}