web-dev-qa-db-fra.com

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

J'ai eu des tests JUnit déjà écrits dans mon projet qui remplissaient les données dans la méthode de configuration. Maintenant, j'ai ajouté maven à mon projet et je veux exécuter tous les cas de test sous forme de maven, c'est-à-dire en utilisant le test mvn. Le problème est maintenant que ma base de données n'est pas effacée après l'exécution de chaque classe de test. J'ai besoin d'effacer la HSQLDB après l'exécution des cas de test de chaque classe.

45
Robin
  1. Vous pouvez effacer les données en supprimant le schéma. Le schéma par défaut est appelé PUBLIC. Si vous exécutez le saturation SQL ci-dessous, il effacera toutes les données et supprimera toutes les tables.

    CASPADE PUBLIQUE DROP SCHEMA

  2. Sinon, si vous avez besoin des définitions d'objets table et 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 apportées aux données ne sont pas persistantes

    files_read_only = true

  3. La dernière alternative, disponible dans HSQLDB 2.2.6 et versions ultérieures, vous 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 AND 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 under Truncate Statement

79
fredt

Suivant les conseils de fredt , TRUNCATE SCHEMA PUBLIC RESTART IDENTITY ET 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 à 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 à leurs valeurs de départ

19
user799188

Ce que nous faisons dans tous nos tests, c'est que nous annulons la transaction à la toute fin de l'exécution (une fois toutes les assertions terminées). Nous utilisons Spring et les tests par défaut ne sont pas validés à la fin. Cela garantit que vous revenez toujours à l'état de départ 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 lancer votre propre try {} finally {} bloquer pour annuler une transaction démarrée pour chaque test.

9
Clement P

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

3
bharath

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

TRUNCATE SCHEMA public AND COMMIT;

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

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