TestsUnitaires:DBUnit
Sommaire
But
DBUnit est une API permettant de tester du code gérant des accès aux bases de données. Ainsi, elle permet avant chaque test, d'initialiser la base de données dans un état prédéfini à l'aide de fichiers XML. Après le déroulement d'un test, d'autres fichiers du même format peuvent servir pour vérifier les données enregistrées.
API et dépendances
Avant d'implémenter des tests, il faut récupérer tous les JAR requis pour les référencer dans le classpath du projet:
Avec Maven, on ajoutera la dépendance suivante dans le fichier pom.xml:
<dependency> <groupId>org.dbunit</groupId> <artifactId>dbunit</artifactId> <version>2.4.7</version> <scope>test</scope> </dependency>
Voir les dernières versions disponibles de DBUnit sur mvnrepository.com.
Implémentation de la classe de test
La classe de test va hériter de la classe org.dbunit.DBTestCase.
Paramétrage de l'accès à la base de données
Dans le constructeur, il faut ajouter les paramètres suivants dans les propriétés systèmes (classe java.lang.System):
- dbunit.driverClass
- dbunit.connectionUrl
- dbunit.username
- dbunit.password
Initialisation de la base de données
Avant chaque test, il faut ré-initialiser la base de données. Pour cela, on créé un fichier XML contenant les données à initialiser au format suivant:
<?xml version='1.0' encoding='UTF-8'?> <dataset> <table name="APPLIANCE_MANUFACTURER"> <column>ID</column> <column>NAME</column> <column>WWW_URL</column> <row> <value>1</value> <value>Orion</value> <value>http://www.telescope.com/</value> </row> <row> <value>2</value> <value><![CDATA[Lunt Solar Systems]]></value> <value>http://www.lunt-solar-systems.com/</value> </row> <row> <value>3</value> <value>ESSAI</value> <value>http://www.essai.fr/</value> </row> </table> </dataset>
Ce fichier XML peut être généré à partir des données déjà stockées en base de données à l'aide du code suivant:
// database connection Class driverClass = Class.forName("org.firebirdsql.jdbc.FBDriver"); Connection jdbcConnection = DriverManager.getConnection("jdbc:firebirdsql:db.srv.minetti.org/3050:test_astro.fdb?lc_ctype=UTF8", "sysdba", "*******"); IDatabaseConnection connection = new DatabaseConnection(jdbcConnection); // partial database export QueryDataSet partialDataSet = new QueryDataSet(connection); partialDataSet.addTable("APPLIANCE_MANUFACTURER"); partialDataSet.addTable("APPLIANCE"); ... FlatXmlDataSet.write(partialDataSet, new FileOutputStream("partial-flat.xml")); XmlDataSet.write(partialDataSet, new FileOutputStream("partial-xml.xml"));
Le fichier XML sera chargé dans la méthode surchargée getDataSet():
@Override protected IDataSet getDataSet () throws Exception { InputStream stream = getClass ().getResourceAsStream ("ExempleTest-refresh.xml"); return new XmlDataSet (stream); }
Ensuite, il faudra définir comment seront initialisées les données avant les tests dans la méthode surchargée getSetUpOperation():
@Override protected DatabaseOperation getSetUpOperation () throws Exception { return DatabaseOperation.CLEAN_INSERT; }
Mais aussi, après les tests dans la méthode surchargée getTearDownOperation():
@Override protected DatabaseOperation getTearDownOperation () throws Exception { return DatabaseOperation.NONE; }
La classe org.dbunit.operation.DatabaseOperation permet d'indiquer les opération suivantes:
Constante | Opération |
---|---|
DatabaseOperation.NONE | Aucune opération. |
DatabaseOperation.UPDATE | Mise à jour des enregistrements:
Cette opération nécessite que les enregistrements existent déjà dans la base de données. Dans le cas contraire, l'opération échoue. |
DatabaseOperation.INSERT | Ajout des enregistrements:
Cette opération nécessite que les enregistrements n'existent pas dans la base de données. Dans le cas contraire, l'opération échoue. Pour éviter des problèmes de violation de clé étrangère, les enregistrements doivent être correctement séquencés dans le fichier XML. |
DatabaseOperation.REFRESH | Rafraîchissement des enregistrements:
Les enregistrements existants dans la base de données sont mis à jour, tandis que les enregistrements absents sont ajoutés. Les enregistrements existants, mais non présents dans le fichier XML, ne sont pas modifiés. |
DatabaseOperation.DELETE | Suppression des enregistrements (présents dans le fichier XML). |
DatabaseOperation.DELETE_ALL | Suppression de tous les enregistrements des tables présentes dans le fichier XML. |
DatabaseOperation.TRUNCATE_TABLE | Tronque tous les enregistrements des tables présentes dans le fichier XML. |
DatabaseOperation.CLEAN_INSERT | Opération DELETE_ALL, suivie d'une opération INSERT. |
- La classe org.dbunit.operation.CompositeOperation permet de faire des combinaisons d'opérations.
- La classe org.dbunit.operation.TransactionOperation permet de décorer une opération pour l'exécuter dans une transaction.
- La classe org.dbunit.ext.mssql.InsertIdentityOperation permet de décorer une opération INSERT pour l'exécuter sans la génération automatique des identifiants (pour MS SQL Server).
Vérification de données
Le code suivant permet de vérifier le contenu d'une table avec le contenu du fichier XML (qui a le même format que celui utilisé pour initialiser la base de données):
IDataSet databaseDataSet = getConnection ().createDataSet (); ITable actualTable = databaseDataSet.getTable ("maTable"); InputStream stream = getClass ().getResourceAsStream ("ExempleTest-insert.xml"); IDataSet expectedDataSet = new XmlDataSet (stream); ITable expectedTable = expectedDataSet.getTable ("maTable"); Assertion.assertEquals (expectedTable, actualTable);
- Pour exclure des colonnes:
actualTable = DefaultColumnFilter.excludedColumnsTable (actualTable, new String[] {"COL_1", "COL_2"});
- Pour trier:
actualTable = new SortedTable(actualTable, new String[] {"ID"});