Использование DbUnit с таблицами, которые не имеют первичных ключей - PullRequest
7 голосов
/ 03 февраля 2012

Я пытаюсь настроить свою среду модульного тестирования на использование 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")); в этом случае?

Большое спасибо за любые советы.

Ответы [ 2 ]

6 голосов
/ 03 февраля 2012

Вы должны убедиться, что ваш MyPrimaryKeyFilter обрабатывает все таблицы в вашей схеме.В этом примере есть только одна таблица, поэтому предоставленный класс простого фильтра работает нормально.В вашем случае, я бы, вероятно, изменил этот класс, чтобы взять Map, содержащий таблицу -> 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 -> A1}, {NO_PK2 ->B1} и {NO_PK3 -> C1} записи.

3 голосов
/ 13 февраля 2013

Я попал в ту же проблему и нашел решение в этих блогах:

Все авторы блога начинаются с http://dbunit.wikidot.com/noprimarykeytable

В этом коде показаны разные стратегии проверки идентификатора:

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