2010-09-30 2 views
3

Comment procéderiez-vous au test unitaire d'un EJB utilisant JPA? Par exemple, si j'ai une entité Order et que OrderEJB est supposé calculer le total d'une commande (tel que défini ci-dessous), comment procéder pour tester l'EJB sans toucher à la base de données? De même, comment définiriez-vous des valeurs pour vos entités, de sorte que vous puissiez affirmer le calcul attendu? Voici quelques exemples de code ci-dessous ...Comment tester les EJB lors de l'utilisation de JPA2?

@Entity 
public class Order { 
    @Id 
    private long OrderId; 
    private LineItem[] items; 
} 

Et un OrderEJB

@Stateless 
public class OrderEJB { 
    EntityManager em; 
    public double calculateOrderTotal(long orderId) { .. } 
} 

Comment iriez-vous de tests unitaires la méthode calculateOrderTotal si je ne peux pas toucher la base de données? Je ne veux pas mettre en œuvre un DAO parce que j'essaie de m'éloigner de cette approche.

Merci pour toute aide.

Répondre

4

N'est-ce pas la théorie générale que OrderEJB et Order et LineItem sont (si nous ignorons l'annotation) juste POJO et peuvent donc être testés en JUnit autonome? Nous aurons besoin de se moquer EntityManager, et vraisemblablement dans

calculateOrderTotal() 

vous avez un code qui dans le concept va

em.giveMeThisOrder(orderId) 

et vous venez de moquez cela. La logique métier que vous testez dépend alors de ce que le Mock renvoie. La clé pour cela est que vous devez utiliser un bon framework de simulation, par exemple JMock. Dans chaque épreuve, vous dites (obviusly pas avec cette syntaxe):

EntitiyManager mockEm = // create the mock 
mockEm.check(that you are called with and order Id of 73) 
mockEm.please(when someone calls giveMeThisOrder return then **this** particular order) 

et ainsi dans chaque test que vous créez exactement l'ordre que vous avez besoin d'exercer certains aspects de votre code calcualtion. Vous pouvez avoir beaucoup de ces tests qui poussent tous les cas de bord et de coin de votre calcul.

L'idée clé ici est que le test unitaire n'implique aucune dépendance externe telle qu'une base de données. Les tests d'intégration pourraient utiliser une base de données réelle. Il peut être fastidieux de corriger vos faux pas, en créant ces instances de commande peut être assez terne, mais il a tendance à rendre les tests futurs beaucoup plus rapide. Je suis également favorable aux tests d'intégration précoce - vous trouvez ainsi toute une autre classe d'erreurs.

+0

Je suis d'accord avec cela +1 –

+0

Mais comment affirmeriez-vous que le calcul est correct, si vous ne savez pas quelles seront les données? Avez-vous besoin d'utiliser des tests d'intégration pour le faire?Peut-être que je mélange les deux, je suis un peu confus à ce que la différence est entre les tests d'intégration et les tests unitaires ... –

+0

Vous ** savez ** ce que les données vont être, je vais mettre à jour le répondre à expliquer. – djna

0

Voici ce que je fais:

Vous devez d'abord mettre en place une base de données en mémoire pour vos tests. Cela fonctionne exactement comme une base de données régulière, mais elle n'est pas stockée sur le disque. Derby et HsqlDB le supportent tous les deux.

Dans votre test unitaire, créez un EntityManager manuellement et injectez-le dans votre instance EJB. Vous aurez probablement besoin de garder une référence à la EntityManager afin que vous puissiez gérer les transactions, comme ceci:

em.getTransaction().begin(); 
myEjb.doSomething(x, y); 
em.getTransaction().commit(); 
+0

Ce n'est pas le test ** unit ** (c'est une approche valide pour les tests d'intégration, mais ce n'est pas un test unitaire). –

+0

Eh bien, si je teste un seul EJB seul, j'appellerais ça un test unitaire. Vous direz probablement que si je le connecte à un fournisseur de persistance, alors je ne le testerai pas "seul" - et je suppose que c'est un poste valide aussi, mais je ne suis pas assez payé pour couper les cheveux . –

+0

Bien, mais comment l'injectez-vous dans l'instance EJB? –

4

Avez-vous donné OpenEJB essayer? - Si vous configurez en mode intégré, vous pouvez exécuter des tests unitaires à partir d'eclipse. Je me suis moqué des injections de gestionnaire d'entité, etc. pour des tests unitaires avant, mais cela devient fastidieux. Avec openejb, vous pouvez le faire avec moins de configuration. http://openejb.apache.org/

+0

Ce ne serait pas un test ** unit ** (isolé). –

+1

Ofcourse il se résume à la façon dont vous voulez aller :) - À mon humble avis l'échafaudage que vous devez créer pour le rendre si isolé ne vaut pas la peine. Je préférerais lancer openejb et hsqldb pour tester mes ejbs sans avoir à craindre de créer des faux-semblants partout. Encore une fois juste mes prises - peut-être cela diffère de beaucoup d'entre vous, je ne sais pas. Aussi oublié d'ajouter ceci à l'article original - http://www.adam-bien.com/roller/abien/entry/how_to_unit_test_ejb – OpenSource

+0

Ceci est une approche très valable pour les tests d'intégration. C'est juste que le PO posait explicitement des questions sur les tests unitaires (et ne touchait pas la base de données). –

Questions connexes