12
votes

Comment charger des données de test DBunit une fois par cas avec test de ressort

Test de ressort permet de reculer utilement les modifications apportées à la base de données dans une méthode de test. Cela signifie qu'il n'est pas nécessaire de prendre le temps de supprimer / recharger les données de test avant chaque méthode de test.

Mais si vous utilisez l'annotation Junit @Beforeclass, alors cela oblige le chargeur de données à être statique. Une question qui est explorée ici: Pourquoi la solution de junit doit-elle être statique?

Si la méthode d'initialisation des données est statique, les méthodes de connexion de données doivent donc et la source de données..et ... et sur ... Forcer tout pour être statique ... qui ne fonctionnera pas. À quel point, je vous demande - quelle est la capacité du test de printemps à annuler des modifications lorsque vous devez supprimer / recharger les données de test de toute façon pour chaque test ??!?!


0 commentaires

5 Réponses :


1
votes

Test de printemps et DBUnit est deux excellentes frameworks. Mais il n'a pas de sens de les combiner. Étant donné que le test de printemps exécute un retour sur la connexion, il se nettoie ensuite, tandis que DBUnit nettoie et insérez des données de test dans la méthode @Before

Utilisez le ressort si vous n'êtes pas dépendant de toutes les données dynamiques et dbunit autrement.


2 commentaires

Je trouve la capacité de Dbunit à charger une table de base de données de XML pour être pratique. Le test de printemps a-t-il une capacité comme celle-ci?


Ouais, je pense que les tapis sont faux ici. Chargement des données de test à partir d'un fichier XML est un bon avantage pour les tests de DB avec le printemps.



1
votes

Nous utilisons dbunit en conjonction avec un test de ressort largement. Mais nous n'utilisons pas la fonctionnalité DBUnit pour supprimer des données à la fin du test.

Nous mettons un tas d'insertions DBUnit pour nos données de test dans la méthode @Before pour initialiser le test. Ensuite, lorsque le test est terminé, nous laissons la fonctionnalité de rollbat à ressort ramener la base de données à son état d'origine.

Le plus gros problème que nous ayons avec cela est que les données DBUnit doivent être chargées avant chaque test, ce qui peut être une performance majeure. La plupart de nos tests utilisant DBUnit sont en lecture seule, testant le comportement de l'application basé sur certains comportements prédéfinis. Nous avons donc l'habitude de créer des tests de maîtres qui exécutent ensuite tous les tests de grains fins dans un lot dans la même transaction.


1 commentaires

Eh bien c'est une mauvaise pratique. Que pensez-vous de la solution vérifiée?



14
votes

Une approche qui fonctionne est de créer une classe "Initialiseur de données", ajoutez-la à un contexte d'application de ressort de test qui possède également votre source de données et filez ce contexte d'application dans vos tests. Cela repose sur le fait que le printemps met en cache le contexte de l'application entre les invocations de test.

Par exemple, une superclasse de test: xxx

avec test-contexte-application. xml : xxx

et xxx

dans cet exemple:

  • Tous les tests qui s'appuient sur la base de données s'étendent dataloadingtest ;
  • Spring initialise le contexte de l'application lors de la première invocation des tests;
  • Cet appelle base de donnéesImitialiser.load () , via le @postConstruct annotation;
  • Spring conserve le contexte de l'application dans un cache;
  • Invocations de test supplémentaires Fil dans le DatabaseInitialis dans le contexte de l'application, qui est déjà mis en cache;
  • Les tests sont transactionnels et roulent à la fin de l'ensemble de données initial.

    De même, DatabaseInitialiser peut avoir une méthode annotée @postDestroy pour effectuer tout retour nécessaire à la fin de l'ensemble du test. < / p>


5 commentaires

C'est en fait exactement comment j'ai résolu le problème, j'ai juste oublié de mettre mon code / de la réponse à la fois. Merci d'avoir pris le temps de le faire pour le prochain gars.


Cela semble bien, mais en pratique, le "@postConstruct" de l'autre classe est en cours d'exécution avant celui de la base de donnéesInitialiseur, il n'est donc pas utile. Merci pour toute aide.


@ United-Expression: Pouvez-vous développer cela? Quelle autre classe voulez-vous dire? Dans l'exemple que j'ai, le printemps initialise l'initialisateur de base de données avant la classe de test, qui fonctionne dans la CASS décrite dans la question.


J'ai une autre classe gérée par le printemps annotée par "@Component", sa méthode "@postConstruct" accède à la DB afin que la classe soit initialisée avant l'initialisateur de base de données. La solution de contournement pour l'instant utilise une annotation personnalisée pour l'autre classe, mais préférerait une meilleure solution. Merci.


J'ai aimé votre approche et je l'ai pris un pas plus loin. Vérifiez ci-dessous ...



0
votes

Méthodes annoté avec @beforetransaction exécuté, comme son nom l'indique, avant que la transaction de chaque test ne soit lancée. Si dans cette méthode, vous pouvez détecter si les données de test sont chargées, on peut charger les données si nécessaire.

Attention, cependant que les données sont laissées dans votre base de données (en mémoire) pour tous les tests suivants .

Nous utilisons cela pour charger des données "statiques" qui seraient, dans un environnement de production, également bootstrapped dans notre base de données lors de la mise en place. De cette façon, nous utilisons réellement exactement le même code et les mêmes données pour nos tests plutôt que de compter sur les exportations (dbunit) qui pourraient devenir obsolètes.


0 commentaires

0
votes

Vous pouvez créer un initialiseur de données "haricot", puisque la configuration est exécutée uniquement une fois. Il suit le même principe que la réponse principale, mais avec moins de code et de classes xxx


0 commentaires