2008-10-24 11 views
1

J'écris des tests pour une méthode métier qui appelle certaines classes DAO pour effectuer des opérations sur une base de données.Comment faire pour simuler des classes instanciées en tant que variables locales

Cette méthode récupère d'abord une connexion JDBC à partir d'un objet DataSource. La même connexion est transmise à toutes les instances DAO, je peux donc l'utiliser pour contrôler la transaction. Donc, si tout fonctionne correctement, je dois invoquer commit() sur l'objet de connexion.

Je voudrais tester si le commit() est invoqué, donc j'ai pensé créer une attente (j'utilise JMock) qui vérifie cela. Mais comme la classe Connection n'est pas un voisin direct de ma classe Business, je ne sais pas comment faire.

Quelqu'un sait comment surmonter cela? Il y a une certaine facilité de JMock pour ceci, ou une conception alternative qui permet de surmonter ceci?

Merci

Répondre

3

Vous devez moquer DataSourceetConnection afin que vos DataSource simulacres ramène votre Connection maquette. Et oui, ce genre de chose finit par devenir une vraie douleur ...

+0

Pourriez-vous me montrer un exemple de code qui montre que c'est fait? – emeraldjava

+0

@emeraldjava: Pas tout à fait, j'ai peur. Il y a longtemps que je n'ai fait aucun JDBC ... –

3

Il m'est difficile de dire exactement comment vos classes sont composées, mais la DataSource doit être injectée dans votre classe DAO, que ce soit par constructeur ou une méthode setDataSource(). Cela vous permettra de tester le DAO de manière isolée, et vous permettra de construire le faux DataSource dans votre test unitaire et le transmettre au DAO testé.

0

Rend la classe bussines récupère les variables locales d'une fabrique d'objets globale/statique. De cette façon, vous pouvez mettre l'usine en mode test et lui faire renvoyer des objets fictifs au lieu de vrais.

Cela devrait le faire.

1

Refactoriser pour que la connexion soit injectée dans le Dao et le Dao injectés dans la classe affaires. Vous pouvez alors se moquer du Dao et/ou de la Connexion. Vous pouvez facilement écrire votre propre maquette qui étend la connexion et remplace connect() pour définir un booléen que vous récupérerez plus tard via une méthode telle que wasConnectCalled().

1

Je vous recommande vivement d'utiliser spring-jdbc au lieu d'essayer d'écrire vous-même ce type de code. Cela garantira que la connexion, l'instruction et le jeu de résultats sont correctement fermés. Spring dispose également d'une excellente gestion des transactions, vous n'avez donc pas à vous en préoccuper.

Par exemple un coup d'oeil à cette déclaration typique de mise à jour à l'aide du printemps-jdbc:

public void updateName(int id, String name) { 
    getJdbcTemplate().update(
      "update mytable set name = ? where id = ?", 
      new Object[] {name, new Integer(id)}); 
} 
0

détaché @ Paul. Et une fois que vous avez séparé la gestion de la connexion, vous pouvez écrire le reste du comportement dans un rappel que vous transmettez à la chose qui possède la connexion - comme un UnitOfWork. Le propriétaire de la connexion gère la transaction et transmet la connexion à UnitOfWork. Transactions en un seul endroit - facile à tester, UnitOfWork dans un autre endroit, testé avec une connexion fictive.

Questions connexes