Java – Android Unit Testing : How to mock a listener that is sent as argument to an asynchronous method?

Android Unit Testing : How to mock a listener that is sent as argument to an asynchronous method?… here is a solution to the problem.

Android Unit Testing : How to mock a listener that is sent as argument to an asynchronous method?

I have a method that can receive listeners (interfaces) with onSuccess(result) and onFail(error) methods.
The test method does something (on another thread) and eventually calls the listener and gives the answer.

Sample code for the method itself (not a test):

testedObject.performAsyncAction("some data", new IListener(){
    @Override
    public void onSuccess(int result) {
        if (result == 1) { /* do something */ }
        else if (result == 2) { /* do something else */ }
    }

@Override
    public void onFailure(Error error) {
        if (error.getMessage().equals("some error")) { /* do something */ }
        else if (error.getMessage().equals("another error")) { /* do something else */ }
    }
});

I would like to do some testing on this method :

    Success

  • when called onSuccess(1).
  • Success

  • when called onSuccess(2).
  • Success when onFailure(new Error(“some error”)).
  • Success on call onFailure(new Error(“another error”)
  • ).

Thanks!

Solution

For this case, I use the Mockito Answer object. This will be a test of success stories:

Answer<Void> myAnswer = new Answer<Void>() {
    public Void answer(InvocationOnMock invocation) {
       Callback callback = (Callback) invocation.getArguments()[1];  second argument in performAsyncAction 
       callback.onSuccess(1);  this would be 1 or 2 in your case
       return null;
    }
};

doAnswer(myAnswer).when(testedObject).performAsyncAction("some data", any(Callback.class));

For failed cases, simply create another test with a different answer. For more information, check out this blog post

Related Problems and Solutions