0

I'm trying to increase my code coverage on Android. But I can't find the correct way to test this presenter. The onSelectContact makes a service call and later my ServiceFactory.getContactService makes another. How can I mock this calls?

public class ContactListPresenter {

    public void onSelectContact(User user) {
        getCorrespondingContactCall(user).enqueue(new Callback <JsonElement>() {
            @Override
            public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
                switch (response.code()) {
                    case case1:
                        goToFirstActivity(user, response);
                        break;
                    case case2:
                        goToSecondActivity(user, response);
                        break;
                    default: showInvalidInput(user);
                        break;
                }
            }

            @Override
            public void onFailure(Call<JsonElement> call, Throwable throwable) {
                if (getView() != null) {
                    getView().showErrorView();
                }
            }
        });
    }

    protected Call<JsonElement> getCorrespondingContactCall(final User user) {
        return StringUtils.isValidEmail(user.getEmail())
                ? ServiceFactory.getContactService().checkContactByEmail(user.getEmail())
                : ServiceFactory.getContactService().checkContactByPhoneNumber(user.getPhoneNumber());
    }     

}
Jose Gonzalez
  • 1,491
  • 3
  • 25
  • 51
  • Are you familiar with PowerMockito for mocking statics ? Eg https://stackoverflow.com/questions/32074356/how-to-android-unit-test-and-mock-a-static-method – racraman Sep 28 '19 at 04:18

1 Answers1

0

If you can - eliminate static calls. For example, by explicitly injecting ContactService to the class under test:

public class ContactListPresenter {
    private final ContactService contactService;

    public ContactListPresenter(ContactService contactService) {
        this.contactService = contactService;
    }

    // rest of the code

    protected Call<JsonElement> getCorrespondingContactCall(final User user) {
        return StringUtils.isValidEmail(user.getEmail())
                ? contactService.checkContactByEmail(user.getEmail())
                : contactService.checkContactByPhoneNumber(user.getPhoneNumber());
    }     
}

This way, in the tests you would be able to easily mock Call<JsonElement> returned by calls to contactService.

However, if changing the code is not an option, you have other alternatives:

  • mock static calls with Powermock

  • use the fact that getCorrespondingContactCall has protected access, by creating anonymous subclass in your test and stub the results of calling getCorrespondingContactCall. For example:

public class ContactListPresenterTest {
   @Test
   public void test() {
      User user = ... // create user for test
      ContactListPresenter presenter = new ContactListPresenter() {
         @Override
         Call<JsonElement> getCorrespondingContactCall(final User user) {
            return ... // stub result of the call
         }
      };
      presenter.onSelectContact(user);
      // assert expected behavior
   }

}
Oleksii Zghurskyi
  • 3,967
  • 1
  • 16
  • 17