web-dev-qa-db-fra.com

Existe-t-il un moyen d’exécuter MySQL en mémoire pour les cas de test JUnit?

J'essaie simplement d'ajouter des scénarios de test pour les services accédant à une base de données MySQL, et j'aimerais recréer le schéma complet (et pour certains scénarios, utilisez simplement un fichier de vidage MySQL avec les données nécessaires à chaque scénario de test). Je cherchais des personnes qui utilisaient SQLite/H2 et d'autres pour le faire, mais je me demandais s'il existait un moyen quelconque d'exécuter MySQL en mémoire, de sorte que je n'ai pas à me soucier de quelque chose de spécifique à MySQL. dialecte que je pourrais utiliser sur nos services.

51
rbajales

Le moyen le plus simple d’utiliser une base de données en mémoire entièrement compatible avec MySQL et utilisable dans les scénarios de test JUnit est le suivant: MariaDB4j . Vous avez simplement besoin d’une dépendance Gradle (/ Maven) ( http: //search.maven .org/# search% 7Cga% 7C1% 7Ca% 3A% 22mariaDB4j% 22 ) et quelques lignes de code pour commencer:

DB database = DB.newEmbeddedDB(3306);
database.start();
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "");

un script de démarrage peut être inclus via

database.source("path/to/resource.sql");

Plus d'informations sur le fichier readme de GitHub: https://github.com/vorburger/MariaDB4j

EDIT: J'ai quelques astuces pour ajouter cette réponse: MariaDB4j semble ajouter des fichiers dans le dossier temporaire du système. Cela fonctionnera donc de manière intégrée, ce qui signifie qu’il n’est pas nécessaire d’installer quoi que ce soit et que vous pouvez simplement utiliser la dépendance via l’outil de construction souhaité. Mais ce n'est pas une vraie solution uniquement en mémoire et par conséquent, nous ne pouvons plus parler de tests unitaires car les tests unitaires ne doivent pas s'appuyer sur des fichiers ou des bases de données.

31

Nous utilisons MySQL et flyway pour gérer la migration. 

Pour les tests unitaires et les tests d'intégration simples, nous utilisons H2 dans la base de données en mémoire avec le paramètre MODE = MySQL. Mode = MySQL permet à la base de données H2 de gérer la plupart des dialectes MySQL. 

Notre source de données de test dans la configuration de Spring est configurée comme suit:

    <bean id="dataSource" class="org.Apache.commons.dbcp.BasicDataSource" >
      <property name="driverClassName" value="org.h2.Driver"/>
      <property name="url" value="jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE" />
    </bean>

(Si vous ne connaissez pas Spring, le code XML correspond à l'appel du nouveau BasicDataSource, puis à l'appel de setDriverClassName et de setUrl sur l'instance créée.)

Ensuite, nous utilisons flyway sur la source de données pour créer le schéma et nous lisons comme si nous utilisions une base de données MySQL classique:

    <bean id="flyway" class="com.googlecode.flyway.core.Flyway" init-method="migrate">
       <property name="dataSource" ref="dataSource" />
       <property name="cleanOnValidationError" value="false" />
       <property name="initOnMigrate" value="true" />
       <property name="sqlMigrationSuffix" value=".ddl" />
    </bean>

Vous pouvez également simplement utiliser le bean dataSource dans un jdbcTemplate et exécuter des scripts SQL de cette manière ou exécuter un certain nombre de scripts MySQL à l'aide de la balise <jdbc:initialize-database...>.

19
joensson

C'est l'une des raisons pour lesquelles utiliser des extensions SQL propriétaires n'est généralement pas une bonne idée.

Ce que je voudrais faire est d'essayer d'identifier les endroits où vous utilisez du SQL non standard et de refactoriser votre code pour déplacer ces parties vers des services dédiés. Ensuite, vous pouvez les imiter lors de l'exécution de tests unitaires.

3
Sean Patrick Floyd

Vous pouvez monter une clé USB (en utilisant ImDisk), y copier vos fichiers de données et démarrer les services Mysql après avoir modifié la configuration appropriée dans my.cnf. , ils peuvent normalement tenir dans un disque ramdrive.

Vous pouvez également envisager d'utiliser la transaction dans vos tests de printemps au lieu de reconstruire les tables à chaque test.

Nous avons utilisé cela pour notre équipe de développeurs et cela a fonctionné à merveille, nous avons gagné un ordre de grandeur en vitesse.

1
David Doumèche

Vous pouvez utiliser un schéma différent pour les tests JUnit. Si vous utilisez Spring, les extensions JUnit permettent à chaque test de s'exécuter dans une transaction en lecture seule. Par conséquent, aucune donnée ne sera persistante dans la base de données après les tests. Si vous avez besoin de données initiales pour les tests, vous devez les insérer dans la méthode marquée @Before qui participe à la transaction.

1
Nicolae Albu

essayez http://hsqldb.org/ , je n'ai pas l'expérience, mais j'ai entendu de bonnes choses.

EDIT Désolé - on dirait que vous voudriez supprimer toute syntaxe spécifique à MySQL ...

0
Galz