47 votes

Comment puis-je effacer les données de ma HSQLDB après chaque test ?

J'avais déjà quelques tests JUnit écrits dans mon projet qui étaient utilisés pour remplir les données dans la méthode setup. Maintenant, j'ai ajouté maven à mon projet et je veux exécuter tous les cas de test à partir de maven, c'est-à-dire en utilisant mvn test. Le problème actuel est que ma base de données n'est pas effacée après l'exécution de chaque classe de test. J'ai besoin de vider la HSQLDB après l'exécution des cas de test de chaque classe.

83voto

fredt Points 10785
  1. Vous pouvez effacer les données en abandonnant le schéma. Le schéma par défaut s'appelle PUBLIC. Si vous exécutez la commande SQL ci-dessous, elle effacera toutes les données et supprimera toutes les tables.

    DROP SCHEMA PUBLIC CASCADE

  2. Alternativement, si vous avez besoin des définitions des objets de table et de schéma, vous pouvez créer un fichier : base de données contenant les objets mais pas de données, et ajouter la propriété ci-dessous au fichier .properties. En utilisant ce type de base de données pour les tests, les modifications des données ne sont pas persistées.

    files_read_only=true

  3. La dernière alternative, disponible dans HSQLDB 2.2.6 et plus, permet d'effacer toutes les données d'un schéma tout en conservant les tables. Dans l'exemple ci-dessous, le schéma PUBLIC est effacé.

    TRUNCATE SCHEMA public ET COMMIT

    Cette déclaration a été améliorée dans les dernières versions de HSQLDB. Voir http://hsqldb.org/doc/2.0/guide/dataaccess-chapt.html#dac_truncate_statement sous Déclaration tronquée

19voto

user799188 Points 3721

Suivant fredt Le conseil de l'entreprise, TRUNCATE SCHEMA PUBLIC RESTART IDENTITY AND COMMIT NO CHECK a fonctionné pour moi. Partie pertinente du code dans le test JUnit pour le DAO.

@After
public void tearDown() {
    try {
        clearDatabase();
    } catch (Exception e) {
        fail(e.getMessage());
    }
}

public void clearDatabase() throws Exception {
  DataSource ds = (DataSource) SpringApplicationContext.getBean("mydataSource");
  Connection connection = null;
  try {
    connection = ds.getConnection();
    try {
      Statement stmt = connection.createStatement();
      try {
        stmt.execute("TRUNCATE SCHEMA PUBLIC RESTART IDENTITY AND COMMIT NO CHECK");
        connection.commit();
      } finally {
        stmt.close();
      }
    } catch (SQLException e) {
        connection.rollback();
        throw new Exception(e);
    }
    } catch (SQLException e) {
        throw new Exception(e);
    } finally {
        if (connection != null) {
            connection.close();
        }
    }
}

Selon la documentation de http://hsqldb.org/doc/2.0/guide/dataaccess-chapt.html#dac_truncate_statement

Si RESTART IDENTITY est spécifié, toutes les séquences IDENTITY de la table et tous les objets SEQUENCE du schéma sont réinitialisés. SEQUENCE du schéma sont réinitialisées à leur valeur initiale.

9voto

Clement P Points 1941

Ce que nous faisons dans tous nos tests, c'est que nous annulons la transaction à la toute fin de l'exécution (une fois que toutes les assertions sont passées). Nous utilisons Spring et, par défaut, les tests ne commettent pas à la toute fin. Cela garantit que vous revenez toujours à l'état initial de la base de données (après la création initiale des tables d'entités et l'exécution de import.sql).

Même si vous n'utilisez pas Spring, vous pouvez probablement créer votre propre try {} finally {} pour annuler une transaction commencée pour chaque test.

3voto

bharath Points 21

Une autre solution est indiquée dans "Effacer la base de données entre les tests". http://www.objectpartners.com/2010/11/09/unit-testing-your-persistence-tier-code/

2voto

Wojtek O. Points 3267

J'avais un simple SQL script qui était exécuté avant chaque test avec l'instruction suivante au début :

TRUNCATE SCHEMA public AND COMMIT;

mais j'ai rencontré des problèmes de verrouillage entre les tests et ajouter ceci a fonctionné pour moi comme un charme :

@After
public void after() throws Exception {
    if (entityManager.getTransaction().isActive()) {
        entityManager.getTransaction().rollback();
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X