2012-02-03 23 views
6

Estoy intentando configurar mi entorno de pruebas unitarias para usar DbUnit.Uso de DbUnit con tablas que no tienen claves principales

Tengo algunos problemas ya que las tablas que estoy intentando controlar no tienen claves principales. He estado recibiendo un org.dbunit.dataset.NoPrimaryKeyException.

que han seguido los pasos aquí http://dbunit.wikidot.com/noprimarykeytable pero ¿cómo se utiliza:

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

para cada uno de mis cuadros?

Por ejemplo, he la siguiente base de datos:

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> 

¿Cómo reescribir connection.getConfig().setProperty("http://www.dbunit.org/properties/primaryKeyFilter", new MyPrimaryKeyFilter("A1")); en este caso?

Muchas gracias por cualquier consejo.

Respuesta

5

Debe asegurarse de que su MyPrimaryKeyFilter maneje todas las tablas de su esquema. En el ejemplo, solo hay una tabla, por lo que la clase de filtro simple proporcionada funciona bien. En su caso, probablemente cambiar esa clase para tomar una tabla que contiene Mapa -> nombre de asignaciones de columnas 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)); 
     } 

    } 

y luego configurar el mapa con {NO_PK1 -> A1}, {NO_PK2 -> B1} , y {NO_PK3 -> C1} entradas.

+0

Gracias slushi. Eso tiene sentido. ¿Qué pasa si una de las tablas tiene una clave compuesta por más de un campo? – mip

+1

creo que allí podría cambiar el Mapa a un Mapa > y hacer un control de contenido. – slushi

+0

Entonces la declaración de retorno se convierte en 'return pseudoKey.get (tableName) .contains (column.getColumnName());'? – mip

3

que caen en mismo problema y la solución que se encuentra en estos blogs:

empezar autores Todo el blog de http://dbunit.wikidot.com/noprimarykeytable

muestra Este código diferente estrategias para verificar 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; 
} 
Cuestiones relacionadas