Using DbUnit with tables which do not have primary keys

天大地大妈咪最大 提交于 2021-02-07 06:23:09

问题


I'm attempting to set up my unit testing environment to use DbUnit.

I'm having a few problems as the tables which I am attempting to control do not have primary keys. I have been getting a org.dbunit.dataset.NoPrimaryKeyException.

I have followed the steps here http://dbunit.wikidot.com/noprimarykeytable but how do I use:

connection.getConfig().setProperty("http://www.dbunit.org/properties/primaryKeyFilter", new MyPrimaryKeyFilter("A1"));

for each of my tables?

For example, I have the following database:

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>

How do I rewrite connection.getConfig().setProperty("http://www.dbunit.org/properties/primaryKeyFilter", new MyPrimaryKeyFilter("A1")); in this instance?

Many thanks for any advice.


回答1:


You need to make sure that your MyPrimaryKeyFilter handles all the tables in your schema. In the example, there is only one table, so the simple filter class provided works fine. In your case, I would probably change that class to take a Map containing table -> pk column name mappings:

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));
        }

    }

and then set up the map with {NO_PK1 -> A1}, {NO_PK2 -> B1}, and {NO_PK3 -> C1} entries.




回答2:


I fall into same issue and found solution in these blogs:

  • http://www.expertaya.com/2011/04/20/dbunit-composite-primary-keys/
  • http://blog.eflow.org/archives/65
  • http://www.baselogic.com/blog/development/test-driven-development/dbunit-unable-import-data-collectiontable-witout-primary-key/

All blog's authors start from http://dbunit.wikidot.com/noprimarykeytable

This code shown different strategies for checking 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;
}


来源:https://stackoverflow.com/questions/9131033/using-dbunit-with-tables-which-do-not-have-primary-keys

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!