Comment puis-je tester le code jdbc dans java?

J’aimerais écrire des tests unitaires pour du code qui se connecte à une firebase database, exécute une ou plusieurs requêtes, puis traite les résultats. (Sans utiliser de firebase database)

Un autre développeur a écrit ici nos propres implémentations DataSource, Connection, Statement, PreparedStatement et ResultSet qui renverront les objects correspondants basés sur un fichier de configuration xml. (nous pourrions utiliser la source de données erronée et exécuter des tests sur les ensembles de résultats renvoyés).

Est-ce que nous réinventons la roue ici? Est-ce que quelque chose comme ça existe déjà pour les tests unitaires? Existe-t-il d’autres moyens / meilleurs pour tester le code jdbc?

Vous pouvez utiliser DBUnit avec un HSQLDB capable de lire ses données initiales à partir de fichiers CSV par exemple.

Vous avez plusieurs options:

  • Mocker la firebase database avec une bibliothèque Mock, par exemple JMock . L’inconvénient majeur de cela est que vos requêtes et les données ne seront probablement pas testées du tout.
  • Utilisez une firebase database légère pour les tests, tels que HSQLDB . Si vos requêtes sont simples, c’est probablement la manière la plus simple de procéder.
  • Dédiez une firebase database pour les tests. DBUnit est une bonne option, ou si vous utilisez Maven, vous pouvez également utiliser le plugin sql-maven pour configurer et supprimer la firebase database correctement (faites attention aux dépendances entre les tests). Je recommande cette option car elle vous donnera la plus grande confiance dans le fait que les requêtes fonctionnent correctement avec votre fournisseur de firebase database.

Il est parfois nécessaire et utile de rendre ces tests configurables afin que ces tests ne soient exécutés que si la firebase database est disponible. Cela peut être fait avec, par exemple, des propriétés de construction.

J’aime utiliser une combinaison de:

  • DBUnit
  • HSQLDB
  • Unitils (en particulier, les modules de test et de maintenance de la firebase database )

Vous pouvez aller assez loin avec juste DBUnit et HSQLDB. Unitils fournit le dernier kilomètre de code pour gérer et réinitialiser l’état de la firebase database. Il offre également un bon moyen de gérer les modifications du schéma de firebase database et facilite l’utilisation de RBDMS spécifiques (Oracle, DB2, SQL Server, etc.). Enfin, Unitils fournit de jolis wrappers autour de DBUnit qui modernisent l’API et rendent DBUnit beaucoup plus agréable à utiliser.

Si vous n’avez pas encore vérifié Unitils, vous devriez le faire. Unitils est souvent négligé et sous-estimé.

Utilisez l’un des frameworks Mock pour une telle tâche. ( jMock , etc. )

Quelques exemples

C’est pourquoi vous avez derby (maintenant appelé JavaDB) ou sqlite – ce sont de petites bases de données simples que vous pouvez créer, charger, tester et détruire relativement rapidement et simplement.

Je dirais que HSQL est la voie à suivre lors de vos tests unitaires. Le but de votre test est de tester votre code jdbc et de vous assurer qu’il fonctionne. Ajouter des classes personnalisées ou simuler les appels jdbc peut facilement masquer les bogues.

J’utilise principalement mysql et lorsque les tests exécutent la classe du pilote et que l’url devient org.hsqldb.jdbcDriver et jdbc: hsqldb: mem: test.

Je préfère utiliser EasyMock pour tester un code pas si facile à tester .

Il y a DBUnit . Il ne vous permettra pas de tester votre code jdbc sans firebase database, mais il semblerait que vous puissiez introduire un ensemble différent d’achats en émulant une firebase database.

Bien que la manière de simuler jdbc dans votre application dépend bien sûr de la manière dont vous avez implémenté vos transactions jdbc réelles.

Si vous utilisez jdbc tel quel, je suppose que vous avez vous-même écrit une classe d’utilitaires pour effectuer certaines tâches dans la ligne DBUtils.getMetadataFor(Ssortingng tablename) . Ce que cela voudrait dire, c’est que vous devriez créer une maquette de cette classe et que c’est tout ce dont vous avez besoin. Ce serait une solution plutôt facile pour vous puisque vous avez apparemment déjà une série d’objects simulés liés à jdbc. Notez que je suppose que votre code jdbc n’est pas explosé tout autour de l’application – si c’est le cas, refactor !!!

Si vous utilisez cependant une structure pour la gestion de firebase database (comme les classes de modèle JDBC de Spring Framework), vous pouvez et devez simuler la classe d’interface avec EasyMock ou un autre équivalent. De cette façon, vous pouvez avoir toute la puissance du monde nécessaire pour vous moquer de la connexion.

Et si rien d’autre ne fonctionne, vous pouvez faire ce que les autres ont déjà dit et utiliser DBUnit et / ou derby.

Si vous voulez faire des tests unitaires, pas des tests d’intégration, vous pouvez utiliser une approche simple et très simple, en utilisant uniquement Mockito, comme ceci:

 public class JDBCLowLevelTest { private TestedClass tested; private Connection connection; private static Driver driver; @BeforeClass public static void setUpClass() throws Exception { // (Optional) Print DriverManager logs to system out DriverManager.setLogWriter(new PrintWriter((System.out))); // (Optional) Sometimes you need to get rid of a driver (eg JDBC-ODBC Bridge) Driver configuredDriver = DriverManager.getDriver("jdbc:odbc:url"); System.out.println("De-registering the configured driver: " + configuredDriver); DriverManager.deregisterDriver(configuredDriver); // Register the mocked driver driver = mock(Driver.class); System.out.println("Registering the mock driver: " + driver); DriverManager.registerDriver(driver); } @AfterClass public static void tearDown() throws Exception { // Let's cleanup the global state System.out.println("De-registering the mock driver: " + driver); DriverManager.deregisterDriver(driver); } @Before public void setUp() throws Exception { // given tested = new TestedClass(); connection = mock(Connection.class); given(driver.acceptsURL(anySsortingng())).willReturn(true); given(driver.connect(anySsortingng(), Matchers.any())) .willReturn(connection); given(connection.prepareCall(anySsortingng())).willReturn(statement); } } 

Que vous pouvez tester différents scénarios, comme dans tout autre test Mockito, par exemple

 @Test public void shouldHandleDoubleException() throws Exception { // given SomeData someData = new SomeData(); given(connection.prepareCall(anySsortingng())) .willThrow(new SQLException("Prepare call")); willThrow(new SQLException("Close exception")).given(connection).close(); // when SomeResponse response = testClass.someMethod(someData); // then assertThat(response, is(SOME_ERROR)); } 

Nous utilisons Mockrunner. http://mockrunner.sourceforge.net/ Il a des connexions simulées et des sources de données intégrées, il n’est donc pas nécessaire de les implémenter vous-même.

Le pilote Acolyte peut être utilisé pour simuler une connexion JDBC, la gérer pendant des tests et renvoyer des données en tant que jeu de résultats (avec son API de liste de lignes type): https://github.com/cchantep/acolyte