2010-10-26 15 views
5

Je voudrais être en mesure de vérifier si chaque unité de travail est effectuée dans sa propre transaction, ou dans le cadre d'une transaction globale unique.Est-il possible de tester la transactionnalité d'un processus?

J'ai une méthode (définie à l'aide du printemps et mise en veille prolongée), ce qui est de la forme:

private void updateUser() { 
    updateSomething(); 
    updateSomethingElse(); 
} 

Ceci est appelé à partir de deux endroits, le site Web lorsqu'un utilisateur se connecte et un traitement par lots qui fonctionne tous les jours . Pour le contexte du serveur Web, il fonctionnera avec une transaction créée par le serveur Web. Pour le travail par lots, il doit avoir une transaction pour chaque utilisateur, de sorte que si quelque chose échoue au cours de cette méthode, la transaction est annulée. Nous avons donc deux méthodes:

@Transactional(propagation=Propagation.REQUIRES_NEW) 
public void updateUserCreateNewTransaction() { 
    updateUser(); 
} 

@Transactional(propagation=Propagation.REQUIRED) 
public void updateUserWithExistingTransaction() { 
    updateUser(); 
} 

updateUserCreateNewTransaction() est appelée à partir du traitement par lots et updateUserWithExistingTransaction() du contexte du serveur web.

Cela fonctionne. Cependant, il est très important que ce comportement (du lot) ne soit pas modifié, donc je souhaite créer un test qui teste ce comportement. Si possible, je voudrais le faire sans changer le code.

donc quelques-unes des options ouvertes à moi sont:

  1. Compter les transactions ouvertes dans la base de données pendant l'exécution du traitement par lots .

  2. Modifiez les données d'une certaine manière de manière à ce qu'au moins une mise à jour de l'utilisateur échoue dans la méthode updateSomethingElse() et vérifiez que updateSomething() n'a pas eu lieu pour cet utilisateur.

  3. Revue de code.

1 est une méthode très dépendante de la base de données, et comment puis-je garantir qu'hibernate ne créera pas de transaction de toute façon? 2 semble mieux, mais est très complexe à mettre en place. 3 n'est pas vraiment pratique parce que nous devrons en faire un pour chaque version.

Alors, est-ce que quelqu'un a une méthode qui me permettrait de tester ce code, de préférence via un test système ou un test d'intégration?

Répondre

2

Je voudrais essayer d'installer un test dans un faisceau de test unitaire en utilisant un HSQLDB en mémoire et EasyMock (ou un autre cadre de simulation).

Vous pouvez alors la méthode updateSomething() vraiment écrire à la base de données HSQL mais utiliser le cadre de simulation pour se moquer de la méthode updateSomethingElse() et jeter un RuntimeException de cette méthode. Lorsque cela est fait, vous pouvez effectuer une requête sur la base HSQLDB pour vérifier que les éléments updateSomething() ont été annulés.

Il faudra un peu de plomberie pour configurer le HSQLDB et le gestionnaire de transactions, mais quand cela est fait, vous avez un test sans dépendances externes qui peuvent être relancé quand vous le souhaitez.