[JAVA] Il est difficile d'utiliser la chaîne de caractères vide et la date de DBUnit, donc corrigez-la et utilisez-la.

1.Tout d'abord

Je pense qu'il existe encore de nombreux cas (2020) d'utilisation de DBUnit comme outil de test unitaire dans des projets de développement Java + RDBMS. DBUnit est un outil très pratique et efficace pour économiser du travail de développement car il peut utiliser le format xls et le format CSV pour les données initiales de DB et les données d'assertion après exécution, mais il est un peu difficile à utiliser en raison du problème du format de données Excel et des spécifications de POI. Il y a un point.

Plus précisément, comme mentionné dans le sujet, il y a un problème qu'il n'est pas possible de distinguer entre une chaîne de caractères vide de type chaîne de caractères variable (type VARCHAR) et NULL, et que la valeur du type de date (DATETIME, TIMESTAMP, DATE, HEURE, etc.) ne peut pas être définie avec précision. Il y a.

Cet article décrit comment résoudre ce problème. La version de DbUnit dans cet article est 2.5.4.

2. Que se passe-t-il avec DBUnit?

2.1 Lire les informations de la cellule

Dans DBUnit, la méthode getValue (int row, String column) de la classe XlsTable obtient la valeur de la cellule Excel et la convertit en la valeur définie dans la base de données.

XlsTable#Extrait de getValue


    int type = cell.getCellType();
    switch (type)
    {
        case HSSFCell.CELL_TYPE_NUMERIC:
            if (HSSFDateUtil.isCellDateFormatted(cell))
            {
                return cell.getDateCellValue();
            }
            return new BigDecimal(cell.getNumericCellValue());

        case HSSFCell.CELL_TYPE_STRING:
            return cell.getStringCellValue();

        case HSSFCell.CELL_TYPE_FORMULA:
            throw new DataTypeException("Formula not supported at row=" +
                    row + ", column=" + column);

        case HSSFCell.CELL_TYPE_BLANK:
            return null;

        case HSSFCell.CELL_TYPE_BOOLEAN:
            return cell.getBooleanCellValue() ? Boolean.TRUE : Boolean.FALSE;

        case HSSFCell.CELL_TYPE_ERROR:
            throw new DataTypeException("Error at row=" + row +
                    ", column=" + column);

        default:
            throw new DataTypeException("Unsupported type at row=" + row +
                    ", column=" + column);
    }

Comme vous pouvez le voir dans le code ci-dessus, si le type de données de la cellule est numérique et dans un format particulier, il s'agit du type de date. En outre, si la cellule est vide, elle est définie sur NULL. Par conséquent, la différence entre les valeurs de type de date définies dans le DB s'affiche en fonction de l'exactitude des données de date dans Excel. Par exemple, sur Excel, ce que vous mettez dans «2020/1/24 10: 00» peut devenir «2020/1/24 10: 00: 01» dans la colonne de type DATETIME de DB. De plus, si la valeur de la cellule est vide, elle sera uniformément nulle, il n'est donc pas possible de créer des données de chaîne de caractères vides.

2.2 Sortie vers les informations de cellule

DBUnit fournit également une fonction pour sortir les données lues à partir de la base de données (mais sans s'y limiter) dans un fichier Excel. La sortie vers Excel est effectuée par la méthode write (IDataSet dataSet, OutputStream out) de la classe XlsDataSet. La valeur à définir dans la cellule est acquise dans la méthode write.

XlsDataSet#Extrait d'écriture


        // write table data
        for (int j = 0; j < table.getRowCount(); j++)
        {
            HSSFRow row = sheet.createRow(j + 1);
            for (int k = 0; k < columns.length; k++)
            {
                Column column = columns[k];
                Object value = table.getValue(j, column.getColumnName());
                if (value != null)
                {
                    HSSFCell cell = row.createCell((short)k);
                    cell.setEncoding(HSSFCell.ENCODING_UTF_16);
                    cell.setCellValue(DataType.asString(value));
                }
            }
        }

Le code ci-dessus récupère la valeur stockée dans ʻITable dans ʻIDataSet et la définit dans la cellule. Si la valeur est «null», la cellule n'est pas générée, donc ce sera une cellule vide sur l'affichage Excel.

3. Comment réparer

À partir du code source DBUnit vu ci-dessus, vous pouvez également voir qu'en plus du contenu de traitement DBUnit lui-même, l'utilisateur ne peut pas modifier la méthode de conversion de la valeur de la cellule Excel pour le type de données. Par conséquent, afin d'utiliser DBUnit commodément, je vais modifier le code source de XlsTable et XlsDataSet pour créer ma propre classe et utiliser DBUnit de cette classe.

3.1 Lecture des informations de cellule

Dans la méthode XlsTable # getValue, modifiez le type de données de la cellule pour définir le type de date s'il correspond au modèle de type de date, même s'il s'agit d'un type chaîne. De plus, si vous écrivez «null» sur la cellule, définissez une valeur NULL dans la base de données.

XlsTable#Réparer getValue


    int type = cell.getCellType();
    switch (type)
    {
        case HSSFCell.CELL_TYPE_NUMERIC:
            if (HSSFDateUtil.isCellDateFormatted(cell))
            {
                return cell.getDateCellValue();
            }
            return new BigDecimal(cell.getNumericCellValue());

        case HSSFCell.CELL_TYPE_STRING:
            /*Mise en œuvre originale (à partir d'ici)*/
            String cellValue = cell.getRichStringCellValue().getString();

            //La valeur de la cellule est"null"Défini sur NULL pour
            if ("null".equals(cellValue)) { return null; }

            //La valeur de la cellule est"yyyy/MM/dd HH:mm:ss"Dans le cas du format, défini en analysant le type de date
            if (Pattern.compile("\\d{4}/\\d{2}/\\d{2} \\d{2}:\\d{2}:\\d{2}").matcher(cellValue).matches()) {
                return new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(cellValue);
            }

            //Autre que ce qui précède, définissez la valeur de la cellule telle quelle
            return cellValue;
            /*Mise en œuvre originale (jusqu'à ici)*/

        case HSSFCell.CELL_TYPE_FORMULA:
            throw new DataTypeException("Formula not supported at row=" +
                    row + ", column=" + column);

        case HSSFCell.CELL_TYPE_BLANK:
            //Si la cellule est vide, renvoie une chaîne vide
            return "";

        case HSSFCell.CELL_TYPE_BOOLEAN:
            return cell.getBooleanCellValue() ? Boolean.TRUE : Boolean.FALSE;

        case HSSFCell.CELL_TYPE_ERROR:
            throw new DataTypeException("Error at row=" + row +
                    ", column=" + column);

        default:
            throw new DataTypeException("Unsupported type at row=" + row +
                    ", column=" + column);
    }

3.2 Sortie vers les informations de cellule

Si vous souhaitez uniquement comparer les paramètres de données initiaux des données JUnit et DB, il vous suffit de corriger la lecture des informations de cellule, mais vous pouvez également utiliser la sortie au format xls des données DB pour rationaliser la création des données de test. Par conséquent, le traitement de sortie des informations de cellule est également corrigé en fonction de la correction de la lecture des informations de cellule.

XlsDataSet#Correction d'écriture


        // write table data
        for (int j = 0; j < table.getRowCount(); j++)
        {
            HSSFRow row = sheet.createRow(j + 1);
            for (int k = 0; k < columns.length; k++)
            {
                Column column = columns[k];
                Object value = table.getValue(j, column.getColumnName());
                /*Mise en œuvre originale (à partir d'ici)*/
                if (null == value) {
                    cell.setCellValue("null");
                } else if (value instanceof java.sql.Timestamp) {
                    cell.setCellValue(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(value));
                } else {
                    cell.setCellValue(DataType.asString(value));
                }
                /*Mise en œuvre originale (jusqu'à ici)*/
            }
        }

Si la valeur est nulle, définissez la valeur de la cellule sur la chaîne «null». Si le type de données est de type Timestamp, définissez une chaîne de caractères au format aaaa / MM / jj HH: mm: ss.

4. Mise en œuvre de sa propre classe

Avec la politique ci-dessus, nous empruntons en fait le code source de XlsDataSet et XlsTable pour définir notre propre classe. Étant donné que la partie modifiée n'utilise que la bibliothèque JDK, je pense qu'elle peut être compilée si l'environnement peut utiliser DBUnit.

Définissez la classe «MyXlsDataSet» comme une version modifiée de «XlsDataSet». La classe XlsTable est définie comme une classe privée de package et n'est pas accessible à partir de packages externes. Ici, nous définissons la classe MyXlsTable comme une classe interne de MyXlsDataSet.

En ce qui concerne le type de date, considérez le type DATE et le type TIME en plus du type DATETIME, définissez un HashMap avec la clé DateFormat comme valeur, et définissez le Motif de chaque clé de Map. S'il est inspecté et correspond, il est analysé par la valeur «DateFormat» associée à la clé. Cela peut être une «Liste» ou un tableau qui stocke une combinaison de «Pattern» et «DateFormat» au lieu de «Map».

Veuillez noter que ce code est uniquement à des fins de test et ne prend pas en compte la synchronisation. Si vous souhaitez utiliser cette classe pour lire un fichier Excel à partir de plusieurs threads, vous devez déterminer s'il faut créer SimpleDateFormat à chaque fois ou le stocker dans ThreadLocal.

MyXlsDataSet


public class MyXlsDataSet extends AbstractDataSet {
    private static final Logger logger = LoggerFactory.getLogger(MyXlsDataSet.class);

    /*Mise en œuvre originale (à partir d'ici)*/
    private static final SimpleDateFormat TIMESTAMP_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd");
    private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss");
    /*Mise en œuvre originale (jusqu'à ici)*/

    private final ITable[] _tables;

    /**
     * Creates a new XlsDataSet object that loads the specified Excel document.
     */
    public DateFormattedXlsDataSet(File file) throws IOException, DataSetException {
        this(new FileInputStream(file));
    }

    /**
     * Creates a new XlsDataSet object that loads the specified Excel document.
     */
    public DateFormattedXlsDataSet(InputStream in) throws IOException, DataSetException {
        HSSFWorkbook workbook = new HSSFWorkbook(in);
        _tables = new ITable[workbook.getNumberOfSheets()];
        for (int i = 0; i < _tables.length; i++) {
            _tables[i] = new DateFormattedXlsTable(workbook.getSheetName(i), workbook.getSheetAt(i));
        }
    }

    /**
     * Write the specified dataset to the specified Excel document.
     */
    public static void write(IDataSet dataSet, OutputStream out)
            throws IOException, DataSetException {
        logger.debug("write(dataSet=" + dataSet + ", out=" + out + ") - start");

        HSSFWorkbook workbook = new HSSFWorkbook();

        int index = 0;
        ITableIterator iterator = dataSet.iterator();
        while (iterator.next()) {
            // create the table i.e. sheet
            ITable table = iterator.getTable();
            ITableMetaData metaData = table.getTableMetaData();
            HSSFSheet sheet = workbook.createSheet(metaData.getTableName());

            // write table metadata i.e. first row in sheet
            // workbook.setSheetName(index, metaData.getTableName(), HSSFWorkbook.ENCODING_UTF_16);
            workbook.setSheetName(index, metaData.getTableName());

            HSSFRow headerRow = sheet.createRow(0);
            Column[] columns = metaData.getColumns();
            for (int j = 0; j < columns.length; j++) {
                Column column = columns[j];
                HSSFCell cell = headerRow.createCell((short) j);
                // cell.setEncoding(HSSFCell.ENCODING_UTF_16);
                cell.setCellValue(column.getColumnName());
            }

            // write table data
            for (int j = 0; j < table.getRowCount(); j++) {
                HSSFRow row = sheet.createRow(j + 1);
                for (int k = 0; k < columns.length; k++) {
                    Column column = columns[k];
                    Object value = table.getValue(j, column.getColumnName());

                    /*Mise en œuvre originale (à partir d'ici)*/
                    HSSFCell cell = row.createCell((short) k);
                    if (null == value) {
                        cell.setCellValue("null");
                    } else if (value instanceof java.sql.Timestamp) {
                        cell.setCellValue(TIMESTAMP_FORMAT.format(value));
                    } else if (value instanceof java.sql.Date) {
                        cell.setCellValue(DATE_FORMAT.format(value));
                    } else if (value instanceof Time) {
                        cell.setCellValue(TIME_FORMAT.format(value));
                    } else {
                        cell.setCellValue(DataType.asString(value));
                    }
                    /*Mise en œuvre originale (jusqu'à ici)*/

                    // if (value != null) {
                    //   HSSFCell cell = row.createCell((short) k);
                    //   cell.setEncoding(HSSFCell.ENCODING_UTF_16);
                    //   cell.setCellValue(DataType.asString(value));
                    // }
                }
            }

            index++;
        }

        // write xls document
        workbook.write(out);
        out.flush();
    }

    ////////////////////////////////////////////////////////////////////////////
    // AbstractDataSet class

    protected ITableIterator createIterator(boolean reversed) throws DataSetException {
        // logger.debug("createIterator(reversed=" + reversed + ") - start");

        return new DefaultTableIterator(_tables, reversed);
    }

    private static class MyXlsTable extends AbstractTable {
        /*Mise en œuvre originale (à partir d'ici)*/
        //Puisqu'il s'agit de UT, la synchronisation n'est pas prise en compte
        private static final HashMap<Pattern, SimpleDateFormat> DATETIME_PATTERN_MAP =
                new HashMap<Pattern, SimpleDateFormat>();

        static {
            DATETIME_PATTERN_MAP.put(
                    Pattern.compile("\\d{4}/\\d{2}/\\d{2}"), new SimpleDateFormat("yyyy/MM/dd"));
            DATETIME_PATTERN_MAP.put(
                    Pattern.compile("\\d{4}-\\d{2}-\\d{2}"), new SimpleDateFormat("yyyy-MM-dd"));
            DATETIME_PATTERN_MAP.put(
                    Pattern.compile("\\d{4}/\\d{2}/\\d{2} \\d{2}:\\d{2}:\\d{2}"),
                    new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"));
            DATETIME_PATTERN_MAP.put(
                    Pattern.compile("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}"),
                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        }
        /*Mise en œuvre originale (jusqu'à ici)*/
        // private static final Logger logger = LoggerFactory.getLogger(XlsTable.class);

        private final ITableMetaData _metaData;
        private final Sheet _sheet;

        private final DecimalFormatSymbols symbols = new DecimalFormatSymbols();

        public DateFormattedXlsTable(String sheetName, Sheet sheet) throws DataSetException {
            int rowCount = sheet.getLastRowNum();
            if (rowCount >= 0 && sheet.getRow(0) != null) {
                _metaData = createMetaData(sheetName, sheet.getRow(0));
            } else {
                _metaData = new DefaultTableMetaData(sheetName, new Column[0]);
            }

            _sheet = sheet;

            // Needed for later "BigDecimal"/"Number" conversion
            symbols.setDecimalSeparator('.');
        }

        static ITableMetaData createMetaData(String tableName, Row sampleRow) {
            logger.debug("createMetaData(tableName={}, sampleRow={}) - start", tableName, sampleRow);

            List columnList = new ArrayList();
            for (int i = 0; ; i++) {
                Cell cell = sampleRow.getCell(i);
                if (cell == null) {
                    break;
                }

                String columnName = cell.getRichStringCellValue().getString();
                if (columnName != null) {
                    columnName = columnName.trim();
                }

                // Bugfix for issue ID 2818981 - if a cell has a formatting but no name also ignore it
                if (columnName.length() <= 0) {
                    // logger.debug("The column name of column # {} is empty - will skip here assuming the
                    // last column was reached", String.valueOf(i));
                    break;
                }

                Column column = new Column(columnName, DataType.UNKNOWN);
                columnList.add(column);
            }
            Column[] columns = (Column[]) columnList.toArray(new Column[0]);
            return new DefaultTableMetaData(tableName, columns);
        }

        ////////////////////////////////////////////////////////////////////////////
        // ITable interface

        public int getRowCount() {
            logger.debug("getRowCount() - start");

            return _sheet.getLastRowNum();
        }

        public ITableMetaData getTableMetaData() {
            logger.debug("getTableMetaData() - start");

            return _metaData;
        }

        public Object getValue(int row, String column) throws DataSetException {
            if (logger.isDebugEnabled()) {
                logger.debug("getValue(row={}, columnName={}) - start", Integer.toString(row), column);
            }

            assertValidRowIndex(row);

            int columnIndex = getColumnIndex(column);
            Cell cell = _sheet.getRow(row + 1).getCell(columnIndex);
            if (cell == null) {
                return null;
            }

            int type = cell.getCellType();
            switch (type) {
                case Cell.CELL_TYPE_NUMERIC:
                    CellStyle style = cell.getCellStyle();
                    if (DateUtil.isCellDateFormatted(cell)) {
                        return getDateValue(cell);
                    } else if (XlsDataSetWriter.DATE_FORMAT_AS_NUMBER_DBUNIT.equals(
                            style.getDataFormatString())) {
                        // The special dbunit date format
                        return getDateValueFromJavaNumber(cell);
                    } else {
                        return getNumericValue(cell);
                    }

                case Cell.CELL_TYPE_STRING:
                    /*Mise en œuvre originale (à partir d'ici)*/
                    String cellValue = cell.getRichStringCellValue().getString();
                    if ("null".equals(cellValue)) {
                        return null;
                    }
                    Set<Pattern> patternSet = DATETIME_PATTERN_MAP.keySet();
                    for (Pattern pattern : patternSet) {
                        if (pattern.matcher(cellValue).matches()) {
                            SimpleDateFormat format = DATETIME_PATTERN_MAP.get(pattern);
                            try {
                                return format.parse(cellValue);
                            } catch (ParseException e) {
                                continue;
                            }
                        }
                    }
                    return cellValue;
                  /*Mise en œuvre originale (jusqu'à ici)*/

                case Cell.CELL_TYPE_FORMULA:
                    throw new DataTypeException("Formula not supported at row=" + row + ", column=" + column);

                case Cell.CELL_TYPE_BLANK:
                    return ""; //Mise en œuvre originale

                case Cell.CELL_TYPE_BOOLEAN:
                    return cell.getBooleanCellValue() ? Boolean.TRUE : Boolean.FALSE;

                case Cell.CELL_TYPE_ERROR:
                    throw new DataTypeException("Error at row=" + row + ", column=" + column);

                default:
                    throw new DataTypeException("Unsupported type at row=" + row + ", column=" + column);
            }
        }

        protected Object getDateValueFromJavaNumber(Cell cell) {
            logger.debug("getDateValueFromJavaNumber(cell={}) - start", cell);

            double numericValue = cell.getNumericCellValue();
            BigDecimal numericValueBd = new BigDecimal(String.valueOf(numericValue));
            numericValueBd = stripTrailingZeros(numericValueBd);
            return new Long(numericValueBd.longValue());
        }

        protected Object getDateValue(Cell cell) {
            logger.debug("getDateValue(cell={}) - start", cell);

            double numericValue = cell.getNumericCellValue();
            Date date = DateUtil.getJavaDate(numericValue);
            return new Long(date.getTime());
        }

        /**
         * Removes all trailing zeros from the end of the given BigDecimal value up to the decimal
         * point.
         *
         * @param value The value to be stripped
         * @return The value without trailing zeros
         */
        private BigDecimal stripTrailingZeros(BigDecimal value) {
            if (value.scale() <= 0) {
                return value;
            }

            String valueAsString = String.valueOf(value);
            int idx = valueAsString.indexOf(".");
            if (idx == -1) {
                return value;
            }

            for (int i = valueAsString.length() - 1; i > idx; i--) {
                if (valueAsString.charAt(i) == '0') {
                    valueAsString = valueAsString.substring(0, i);
                } else if (valueAsString.charAt(i) == '.') {
                    valueAsString = valueAsString.substring(0, i);
                    // Stop when decimal point is reached
                    break;
                } else {
                    break;
                }
            }
            BigDecimal result = new BigDecimal(valueAsString);
            return result;
        }

        protected BigDecimal getNumericValue(Cell cell) {
            logger.debug("getNumericValue(cell={}) - start", cell);

            String formatString = cell.getCellStyle().getDataFormatString();
            String resultString = null;
            double cellValue = cell.getNumericCellValue();

            if ((formatString != null)) {
                if (!formatString.equals("General") && !formatString.equals("@")) {
                    logger.debug("formatString={}", formatString);
                    DecimalFormat nf = new DecimalFormat(formatString, symbols);
                    resultString = nf.format(cellValue);
                }
            }

            BigDecimal result;
            if (resultString != null) {
                try {
                    result = new BigDecimal(resultString);
                } catch (NumberFormatException e) {
                    logger.debug("Exception occurred while trying create a BigDecimal. value={}",
                            resultString);
                    // Probably was not a BigDecimal format retrieved from the excel. Some
                    // date formats are not yet recognized by HSSF as DateFormats so that
                    // we could get here.
                    result = toBigDecimal(cellValue);
                }
            } else {
                result = toBigDecimal(cellValue);
            }
            return result;
        }

        /**
         * @param cellValue
         * @return
         * @since 2.4.6
         */
        private BigDecimal toBigDecimal(double cellValue) {
            String resultString = String.valueOf(cellValue);
            // To ensure that intergral numbers do not have decimal point and trailing zero
            // (to restore backward compatibility and provide a string representation consistent with
            // Excel)
            if (resultString.endsWith(".0")) {
                resultString = resultString.substring(0, resultString.length() - 2);
            }
            BigDecimal result = new BigDecimal(resultString);
            return result;
        }

        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append(getClass().getName()).append("[");
            sb.append("_metaData=").append(this._metaData == null ? "null" : this._metaData.toString());
            sb.append(", _sheet=").append(this._sheet == null ? "null" : "" + this._sheet);
            sb.append(", symbols=").append(this.symbols == null ? "null" : "" + this.symbols);
            sb.append("]");
            return sb.toString();
        }
    }
}

Le code source cité était le dernier 2.6.0 au 24 janvier 2020, mais comme la version de DBUnit utilisée pour la vérification est 2.5.4, j'ai commenté les paramètres liés à l'encodage Excel. .. Si vous souhaitez utiliser la version 2.6.0 ou supérieure, veuillez décommenter la ligne suivante.

            // workbook.setSheetName(index, metaData.getTableName(), HSSFWorkbook.ENCODING_UTF_16);
                // cell.setEncoding(HSSFCell.ENCODING_UTF_16);

5. Utilisez votre propre classe

Si la classe propriétaire ci-dessus est compilée avec succès, l'utilisation est exactement la même que celle de XlsDataSet. Cependant, comme DBUnit n'autorise pas la sortie de cellules vides par défaut, il est préférable d'ajouter un processus pour définir DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS sur true pour la DatabaseConnection acquise.

Définir les données Excel dans DB


    DatabaseConnection connection = new DatabaseConnection(sqlConnection, schemaName);
    connection.getConfig().setProperty(DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS, true);
    IDataSet xlsDataSet = new MyXlsDataset(new File(xlsFilePath));
    DatabaseOperation.CLEAN_INSERT.execute(connection, compositDataSet);

Comparez les données Excel et la base de données


    DatabaseConnection connection = new DatabaseConnection(sqlConnection, schemaName);
    connection.getConfig().setProperty(DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS, true);
    IDataSet expected= new MyXlsDataset(new File(expectedXlsFilePath));
    QueryDataSet actual = new QueryDataSet(connection);
    Assert.assertEquals(expected, actual);

Sortie des données de base de données dans un fichier Excel


    DatabaseConnection connection = new DatabaseConnection(sqlConnection, schemaName);
    connection.getConfig().setProperty(DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS, true);
    QueryDataSet dbDataSet= new QueryDataSet(connection);
    FileOutputStream fileOutputStream = new FileOutputStream(outputFilePath);
    MyXlsDataset.write(dbDataSet, fileOutputStream);

Pour les projets qui utilisent gradle, vous souhaiterez peut-être utiliser DBUnit comme tâche gradle pour exporter ou importer des bases de données. Bien sûr, cela est possible, mais dans ce cas, la classe MyXlsDataSet ci-dessus devrait être une bibliothèque jar.

6. Enfin

DBUnit dispose d'une licence LGPL. Veuillez noter que si vous souhaitez inclure le code ci-dessus dans le code d'implémentation, par exemple lors de la distribution du code de test du programme créé, vous devez vous conformer à la licence LGPL.

Recommended Posts

Il est difficile d'utiliser la chaîne de caractères vide et la date de DBUnit, donc corrigez-la et utilisez-la.
[Swift] Si le support de l'application est iOS 11 ou version ultérieure, il n'était pas nécessaire d'utiliser correctement Int et Int64
Est-il possible de mettre la bibliothèque (aar) dans la bibliothèque Android (aar) et de l'utiliser?
[Java] Utilisez ResolverStyle.LENIENT pour bien gérer la date et l'heure
Est-il facile à utiliser pour l'utilisateur lors de la mise en œuvre de fonctions à usage général? Soyons conscients de
Le concept de conception de l'API de date et d'heure de Java est intéressant
J'ai essayé de résumer les méthodes de Java String et StringBuilder
Ajoutez la date aux statistiques GC acquises par gcutil et affichez-la.
(Déterminez en 1 minute) Comment utiliser vide?, Vide? Et présent?
Obtenez le type d'un élément d'un tableau pour déterminer s'il s'agit d'un tableau
Comme la commande du utilisée lorsque la capacité est pleine est difficile à utiliser, j'ai essayé de l'envelopper avec du rubis
[Java] Est-il inutile de vérifier "l'identité" dans l'implémentation de la méthode equals ()?
Est-il courant de ne pas écrire la balise de fermeture de la balise <P> dans Javadoc?
[Java] Lors de la mise d'une chaîne de caractères dans le cas de l'instruction switch, il est nécessaire d'en faire une expression constante
L'argument de link_to est nul (nul) et un lien inattendu a été généré, j'ai donc essayé de le vérifier
Code difficile à déboguer et à analyser
[Java] La partie déroutante de String et StringBuilder
Sortie de la façon d'utiliser la méthode slice
[Java] Comment utiliser la classe Calendar et la classe Date
[Java] J'ai étudié le polymorphisme, je vais donc résumer comment l'utiliser et ses mérites.
Comment créer un en-tête ou un pied de page une fois et l'utiliser sur une autre page
Créez un package qui est une partie de développement commune d'Automation Anywhere A2019 # 1 ~ Commencez par créer et utiliser l'exemple de SDK tel quel