Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I mock a method in easymock that shall return one of its parameters?

public Object doSomething(Object o); which I want to mock. It should just return its parameter. I tried:

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

but without success, I get just an AssertionError as java.lang.AssertionError: Nothing captured yet. Any ideas?

like image 767
Jan Avatar asked Apr 19 '10 12:04

Jan


People also ask

Which of the given method is used to create EasyMock?

EasyMock provides various methods to create mock objects. EasyMock. createMock() creates mocks without bothering about the order of method calls that the mock is going to make in due course of its action.

How does EasyMock test private methods?

If you still want to use EasyMock, because changing it doesn't depend on you (work in an enterprise) you can use reflection to change the private field which your method returns, or any private field for that matter. You can have these methods in a helper class for example. And use them as needed.


2 Answers

Well, the easiest way would be to just use the Capture in the IAnswer implementation... when doing this inline you have to declare it final of course.

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) 

This is probably the most exact way, without relying on some context information. This does the trick for me every time.

like image 192
does_the_trick Avatar answered Sep 28 '22 08:09

does_the_trick


I was looking for the same behavior, and finally wrote the following :

 import org.easymock.EasyMock; import org.easymock.IAnswer;  /**  * Enable a Captured argument to be answered to an Expectation.  * For example, the Factory interface defines the following  * <pre>  *  CharSequence encode(final CharSequence data);  * </pre>  * For test purpose, we don't need to implement this method, thus it should be mocked.  * <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(parrot).anyTimes();  * </pre>  * Created on 22 juin 2010.  * @author Remi Fouilloux  *  */ public class ArgumentAnswer<T> implements IAnswer<T> {      private final int argumentOffset;      public ArgumentAnswer() {         this(0);     }      public ArgumentAnswer(int offset) {         this.argumentOffset = offset;     }      /**      * {@inheritDoc}      */     @SuppressWarnings("unchecked")     public T answer() throws Throwable {         final Object[] args = EasyMock.getCurrentArguments();         if (args.length < (argumentOffset + 1)) {             throw new IllegalArgumentException("There is no argument at offset " + argumentOffset);         }         return (T) args[argumentOffset];     }  }  

I wrote a quick "how to" in the javadoc of the class.

Hope this helps.

like image 22
rems Avatar answered Sep 28 '22 10:09

rems