2009-02-04 8 views
42

J'utilise Mockito pour écrire un test unitaire en Java, et je voudrais vérifier qu'une certaine méthode est la dernière appelée sur un objet.Utiliser Mockito pour vérifier que rien n'est appelé après une méthode

que je fais quelque chose comme cela dans le code sous test:

row.setSomething(value); 
row.setSomethingElse(anotherValue); 
row.editABunchMoreStuff(); 
row.saveToDatabase(); 

Dans ma maquette, je ne se soucient pas de l'ordre dans lequel je modifie tout sur la ligne, mais il est très important que Je pas essayer de faire quelque chose de plus après que je l'ai enregistré. Y at-il un bon moyen de le faire?

Notez que je ne recherche pas verifyNoMoreInteractions: il ne confirme pas que saveToDatabase est la dernière chose appelée, et il échoue également si j'appelle quoi que ce soit sur la ligne que je ne vérifie pas explicitement. Je voudrais pouvoir dire quelque chose comme:

verify(row).setSomething(value); 
verify(row).setSomethingElse(anotherValue); 
verifyTheLastThingCalledOn(row).saveToDatabase(); 

Si elle aide, je passe à Mockito d'un test de JMock qui a fait ceci:

row.expects(once()).method("saveToDatabase").id("save"); 
row.expects(never()).method(ANYTHING).after("save"); 
+5

Une note de l'avenir: nous refactorisé finalement cela pour éviter la dépendance de l'ordre. Plus précisément, nous avons déplacé la partie saveToDatabase() vers une couche externe du code, où elle serait automatiquement appelée au bon moment. En général, si vous avez besoin de faire quelque chose comme ça avec un simulacre, vos tests vous disent de refactoriser. Cela dit, il est toujours agréable d'avoir un test qui peut fonctionner jusqu'à ce que le design soit changé. –

Répondre

52

Je pense qu'il a besoin de plus sur mesure travail.

verify(row, new LastCall()).saveToDatabase(); 

puis

public class LastCall implements VerificationMode { 
    public void verify(VerificationData data) { 
     List<Invocation> invocations = data.getAllInvocations(); 
     InvocationMatcher matcher = data.getWanted(); 
     Invocation invocation = invocations.get(invocations.size() - 1); 
     if (!matcher.matches(invocation)) throw new MockitoException("..."); 
    } 
} 

Réponse précédente:

Vous avez raison. verifyNoMoreInteractions est ce dont vous avez besoin.

verify(row).setSomething(value); 
verify(row).setSomethingElse(anotherValue); 
verify(row).editABunchMoreStuff(); 
verify(row).saveToDatabase(); 
verifyNoMoreInteractions(row); 
+0

Non ce n'est pas le cas. J'ai mis à jour la question pour clarifier pourquoi. –

+0

Oh wow. J'avais raté votre mise à jour jusqu'à ce que je passais en revue les anciennes questions tout à l'heure, sinon je l'aurais upvoted plus tôt. Cela ressemble exactement à ce dont j'ai besoin. Merci! –

+1

erreur de compilation: ne peut pas être résolu – kmalmur

0

Cette question m'a amené à faire quelques améliorations à la API Verifications JMockit (disponible dans la prochaine version 0,983).

La solution que je suis venu avec vous permet d'écrire (dans une méthode d'essai):


    new VerificationsInOrder() {{ 
     unverifiedInvocations(); 
     row.saveToDababase(); 
    }}; 

... si vous voulez seulement vérifier qu'une certaine méthode est appelée après tout le reste. Pour vérifier qu'il se passe avant toutes les autres invocations, il suffit de déplacer l'appel vers le haut. Cela s'applique en fait à toute séquence d'invocations consécutives.

Si, en plus de la vérification ci-dessus, vous voulez également vérifier que d'autres méthodes sont appelées dans l'ordre, une seconde vérifications bloc peut être ajouté à l'épreuve (avant ou après l'autre bloc, il n » t la matière):


    new Verifications() {{ 
     row.setSomething(value); 
     row.setSomethingElse(anotherValue); 
    }}; 

Bien qu'un peu long à cause de l'utilisation des classes internes anonymes, cette syntaxe est à la fois simple et flexible; remarquez comment il ajoute la structure au test et évite la répétition des appels de méthode (comme verify(...)). Il y a plus que ce que je décris ici (matcheurs Hamcrest, nombre d'invocations, etc.), et cela ne se limite pas à la vérification des méthodes d'instance (les méthodes statiques et les constructeurs peuvent être moqués et vérifiés de la même manière).

9

Pas 100% sur le sujet mais je cherchais juste à trouver le contraire de vérifier, et c'était le seul résultat pertinent, il finit par être après Mockito.verifyZeroInteractions (mock);

Juste Incase quelqu'un d'autre se termine à chercher ici pour cette ...

Questions connexes