web-dev-qa-db-fra.com

Comment puis-je simuler une méthode dans easymock qui doit retourner l'un de ses paramètres?

public Object doSomething(Object o); dont je veux me moquer. Il devrait simplement retourner son paramètre. J'ai essayé:

Capture<Object> copyCaptcher = new Capture<Object>();
expect(mock.doSomething(capture(copyCaptcher)))
        .andReturn(copyCatcher.getValue());

mais sans succès, je reçois juste une AssertionError comme Java.lang.AssertionError: Nothing captured yet. Des idées?

30
Jan

Je cherchais le même comportement et j'ai finalement écrit ce qui suit:

 import org.easymock.EasyMock; 
 import org.easymock.IAnswer; 
 
/** 
 * Activer la réponse à un argument capturé à une attente. 
 * Par exemple, l'interface Factory définit le 
 * <pre> 
 * codage CharSequence suivant (données CharSequence finales); 
 * <//pre> 
 * À des fins de test, nous n'avons pas besoin d'implémenter cette méthode, elle doit donc être simulée. 
 * <pre> 
 * final Factory factory = mocks.createMock ("factory", Factory.class); 
 * final ArgumentAnswer <CharSequence> parrot = new ArgumentAnswer <CharSequence> (); 
 * EasyMock.expect (factory.encode (EasyMock.capture (new) Capture <CharSequence> ()))). AndAnswer (perroquet) .anyTimes (); 
 * </pre> 
 * Créé le 22 juin 2010. 
 * @Author Remi Fouilloux 
 * 
 */
 Classe publique ArgumentAnswer <T> implémente IAnswer <T> {
 
 Private final int argumentOffset; 
 
 public ArgumentAnswer () {
 t his (0); 
} 
 
 public ArgumentAnswer (int offset) {
 this.argumentOffset = offset; 
} 
 
 /**
 * {@inheritDoc} 
 */
 @SuppressWarnings ("non coché") 
 public T answer () throws Throwable { 
 final Object [] args = EasyMock.getCurrentArguments (); 
 if (args.length <(argumentOffset + 1)) {
 lever une nouvelle exception IllegalArgumentException ("Il n'y a pas d'argument à offset "+ argumentOffset); 
} 
 return (T) args [argumentOffset]; 
} 
 
} 
 

J'ai écrit un rapide "mode d'emploi" dans le javadoc de la classe.

J'espère que cela t'aides.

18
rems

Eh bien, le moyen le plus simple serait d'utiliser simplement Capture dans l'implémentation IAnswer ... lorsque vous faites cela en ligne, vous devez le déclarer final bien sûr.

MyService mock = createMock(MyService.class);

final Capture<ParamAndReturnType> myCapture = new Capture<ParamAndReturnType>();
expect(mock.someMethod(capture(myCapture))).andAnswer(
    new IAnswer<ParamAndReturnType>() {
        @Override
        public ParamAndReturnType answer() throws Throwable {
            return myCapture.getValue();
        }
    }
);
replay(mock)

C'est probablement le moyen le plus exact, sans s'appuyer sur certaines informations contextuelles. Cela fait l'affaire à chaque fois pour moi.

26
does_the_trick

Les captures sont destinées à tester les valeurs passées à la maquette par la suite. Si vous n'avez besoin que d'une maquette pour renvoyer un paramètre (ou une valeur calculée à partir du paramètre), il vous suffit d'implémenter IAnswer.

Voir l'implémentation de "Remi Fouilloux" si vous voulez un moyen réutilisable de renvoyer le paramètre X, mais ignorez son utilisation de Capture dans l'exemple.

Si vous voulez juste l'inclure comme dans l'exemple de "does_the_trick", encore une fois, la capture est un hareng rouge ici. Voici la version simplifiée:

MyService mock = createMock(MyService.class);
expect(mock.someMethod(anyObject(), anyObject()).andAnswer(
    new IAnswer<ReturnType>() {
        @Override
        public ReturnType answer() throws Throwable {
            // you could do work here to return something different if you needed.
            return (ReturnType) EasyMock.getCurrentArguments()[0]; 
        }
    }
);
replay(mock)
15
thetoolman

Sur la base de @does_the_trick et en utilisant des lambdas, vous pouvez maintenant écrire ce qui suit:

MyService mock = EasyMock.createMock(MyService.class);

final Capture<ParamAndReturnType> myCapture = EasyMock.newCapture();
expect(mock.someMethod(capture(myCapture))).andAnswer(() -> myCapture.getValue());

ou sans capture comme l'a suggéré @thetoolman

expect(mock.someMethod(capture(myCapture)))
.andAnswer(() -> (ParamAndReturnType)EasyMock.getCurrentArguments()[0]);
9
Marco Baumeler

Si je comprends bien votre question, je pense que vous pourriez être en train de la compliquer.

Object someObject = .... ;
expect(mock.doSomething(someObject)).andReturn(someObject);

Devrait fonctionner très bien. N'oubliez pas que vous fournissez à la fois le paramètre attendu et la valeur de retour. Donc, en utilisant le même objet dans les deux œuvres.

2
drekka