web-dev-qa-db-fra.com

EasyMock: Void Méthodes

J'ai une méthode qui renvoie void dans une classe qui est une dépendance de la classe que je veux tester.

Cette classe est énorme et je n'utilise que cette seule méthode. Je dois remplacer l'implémentation de cette méthode pour le test car je veux qu'elle fasse quelque chose de différent et je dois pouvoir accéder aux paramètres que cette méthode reçoit.

Je ne peux pas trouver un moyen de le faire dans EasyMock . Je pense que je sais comment le faire avec Mockito en utilisant doAnswer mais je ne veux pas ajouter une autre bibliothèque à moins que cela ne soit absolument nécessaire.

68
Iker Jimenez

Si je comprends bien ce que vous voulez faire, vous devriez pouvoir utiliser andAnswer():

mockObject.someMethod(eq(param1), eq(param2));
expectLastCall().andAnswer(new IAnswer() {
    public Object answer() {
        //supply your mock implementation here...
        SomeClass arg1 = (SomeClass) getCurrentArguments()[0];
        AnotherClass arg2 = (AnotherClass) getCurrentArguments()[1];
        arg1.doSomething(blah);
        //return the value to be returned by the method (null for void)
        return null;
    }
});

Le EasyMock User Guide explique:

Création de valeurs de retour ou d'exceptions

Parfois, nous aimerions que notre objet fictif renvoie une valeur ou lève une exception qui est créée au moment de l'appel réel. Depuis EasyMock 2.2, l'objet renvoyé par expectLastCall() et expect(T value) fournit la méthode andAnswer(IAnswer answer) qui permet à [vous] de spécifier une implémentation de l'interface IAnswer qui est utilisée pour créer la valeur de retour ou l'exception.

Dans un rappel IAnswer , les arguments passés à l'appel simulé sont disponibles via EasyMock.getCurrentArguments() . Si vous les utilisez, des refactorings comme les paramètres de réorganisation peuvent casser vos tests. Tu étais prévenu.

91
matt b

Si vous appelez simplement la méthode void pour chaque fois que vous vous attendez à ce qu'elle soit invoquée, puis invoquez EasyMock.expectLastCall() avant d'appeler replay(), Easymock se "souviendra" de chaque invocation.

Je ne pense donc pas que vous ayez besoin d'appeler explicitement expect() (autre que lastCall) car vous n'attendez rien d'une méthode void, sauf son invocation.

Merci Chris!

"Fun With EasyMock" par un autre utilisateur de StackOverflow Burt Beckwith est un bon article de blog qui fournit plus de détails. Extrait notable:

Fondamentalement, le flux que j'ai tendance à utiliser est le suivant:

  1. Créer une maquette
  2. appeler expect(mock.[method call]).andReturn([result]) pour chaque appel attendu
  3. appeler mock.[method call], puis EasyMock.expectLastCall() pour chaque appel annulé attendu
  4. appeler replay(mock) pour passer du mode "enregistrement" au mode "lecture"
  5. injecter la maquette au besoin
  6. appeler la méthode de test
  7. appelez verify(mock) pour vous assurer que tous les appels attendus se sont produits
22

Si vous ne souhaitez accéder aux paramètres que pour plus tard, vous pourriez également apprécier la classe Captures qui est nouvelle dans EasyMock 2.4.

Vous pouvez utiliser une instance de la classe "Capture" à la place d'une correspondance. Lorsque votre méthode simulée est invoquée, l'instance Capture stockera le paramètre avec lequel elle a été invoquée.

Capture<ChartPanel> captured = new Capture<ChartPanel>();
// setChartPanel is going to be called during execution;
// we want to verify some things about the ChartPanel
// instance it's invoked with
chartMock.setChartPanel(capture(captured));
replay(chartMock);

ufdm.setChartAnnotater(chartMock);
// afterPropertiesSet triggers the setChartPanel call...
ufdm.afterPropertiesSet();
verify(chartMock);

// verify some things about the ChartPanel parameter our
// mock object was invoked with
assertSame(plot, captured.getValue().getChart().getPlot());
5
piepera

Vous voudrez peut-être consulter PowerMock. EasyMock est basé sur l'API de réflexion de proxy, ce qui signifie que tout est un proxy et que vous ne pouvez tester que des interfaces, et donc uniquement des méthodes et des classes non finales. Cela peut fonctionner pour certains, mais si vous testez le monde tel qu'il est construit, vous aurez besoin de plus de puissance.

Avec PowerMock, l'API d'instrumentation Java 5 supprime les limitations. Pas besoin d'écrire des implémentations d'objet simulé de l'objet à tester (juste laid IMO). Couple PowerMock avec Mockito (ou JMockit) et vous '' Je serai vraiment partant pour les courses.

Bien sûr, il y a l'autre sens de réécrire votre code pour qu'il soit plus facilement testé, ce qui est généralement une bonne idée aussi, si possible.

1
Joseph Lust