Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a method that receives a listener (interface) with onSuccess(result) and onFail(error) methods.
The tested method performs some actions (on another thread) and eventually calls the listener with an answer.

Example code for the method itself (not the 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 want to have few tests on this method:

  • Success when onSuccess(1) is called
  • Success when onSuccess(2) is called
  • Success when onFailure(new Error("some error")) is called
  • Success when onFailure(new Error("another error")) is called

Thank you!

like image 942
Michael Kessler Avatar asked Oct 31 '22 06:10

Michael Kessler


1 Answers

For this case I use the Mockito Answer object. This would be a test for a success case:

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 the failure case, just create another test with a different answer. For more info, check this blog post.

like image 60
Yair Kukielka Avatar answered Nov 11 '22 11:11

Yair Kukielka