Been working with GWT a lot recently. MVP allows easier unit testing of the client logic, but those asynchronous RPC callbacks are usually implemented as anonymous inner classes which are a bitch to test.
However, they can be mocked out and tested with a custom stubber like this.
public static class AsyncMockStubber { private static <T> Stubber callSuccessWith(final T data) { return Mockito.doAnswer(new Answer<T>() { @Override @SuppressWarnings("unchecked") public T answer(InvocationOnMock invocationOnMock) throws Throwable { final Object[] args = invocationOnMock.getArguments(); ((AsyncCallback) args[args.length - 1]).onSuccess(data); return null; } }); } }
Its nice that the async interface always has the callback as the last parameter, so one size fits all.
AsyncMockStubber.callSuccessWith(data).when(armorService).getData(any(AsyncCallback.class));
Hello Tim, I started learning Mockito an hour or so ago and I want to apply your code above to testing my GWT activities (presenters). However, I’m having trouble understanding the context in which you use your call to “syncMockStubber.callSuccessWith(data)…”. Would it be possible to provide a line or two of sample code that would proceed and follow this line of code? Thanks, Chuck
Hi Chuck,
I’m trying to test the behaviour of the class with an AsyncCallback which is often an anonymous inner class like this example from a presenter method:
Typically, onSuccess() will either call to update the display or fire an event.
You’ll have the async service setup to mirror your server side service
The test might look something like this:
..will simulate that any call to the service.getData() will invoke onSuccess() so you can test the behaviour of the whole method with a successful async response. A similar stubber can be made for the onFailure() method.
[…] http://blog.reflectedcircle.com/2009/12/08/gwt-rpc-asynccallback-testing-using-mockito/ […]
Hi Tim,
I am trying to write a test case using Mockito for the sample code that GWT generates(GreetingServiceAsync.java and I am using Eclipse Helios). I tried the code snippet you have shared here. For some reason it is not recognizing the method “any(AsyncCallBack.class)”.
If possible could you mail me the code so that I can understand what exactly Mockito is trying to do? It would be really helpful.
Thanks,
Yogesh
Hi Yogesh,
I don’t have the code this was derived from, it was based on a project at work, so classes and variable names have been changed to protect the innocent.
The any() method is one of the Mockito Matchers.
I suspect the issue is that when one parameter is a matcher, then all the parameters should be matchers also. If they are actual objects, then just wrap them in the eq() matcher.
e.g.
@Yogesh
I hope this is not too late but for this issue:
| For some reason it is not recognizing the method “any(AsyncCallBack.class)”.
You need to,
import static org.mockito.Mockito.any;
@David,@Yogesh
you need import static org.mockito.Matchers.any;