Ali
Ali

Reputation: 9994

Unit test while using retrofit

I have following Service interface for retrofit :

public interface TimetableService {

    @GET("url/")
    Call<Flixbus> getTimetable();
}

I want to test UI after retrofit call :

@RunWith(AndroidJUnit4.class)
public class TestTimetablePresenter {

    private static List<Departure> DEPARTURES = Lists.newArrayList(
            new Departure("L006", "Stockholm",
                    new Datetime(1461056400, "GMT+02:00")),
            new Departure("L007", "Berlin",
                    new Datetime(1461056500, "GMT+02:00")));

    @Mock
    private TimetableContract.View mTimetableView;

    @Mock
    private TimetableService mockTimetableServiceImpl;

    @Captor
    private ArgumentCaptor<Callback<Flixbus>> mCallbackArgumentCaptor;

    private TimetablePresenter mNotesPresenter;



    @Before
    public void setupNotesPresenter() {
        MockitoAnnotations.initMocks(this);

        SampleApp mApp = (SampleApp) InstrumentationRegistry.getInstrumentation()
                .getTargetContext().getApplicationContext();

        mNotesPresenter = new TimetablePresenter(mApp, mTimetableView);

        mNotesPresenter.setWebService(mockTimetableServiceImpl);
    }

    @Test
    public void loadDeparturesFromAPIAndLoadIntoView() {

      mNotesPresenter.loadDepartures();

        Mockito.verify(mockTimetableServiceImpl).getTimetable().enqueue(mCallbackArgumentCaptor.capture());

        InOrder inOrder = Mockito.inOrder(mTimetableView);
        inOrder.verify(mTimetableView).setProgressIndicator(true);
        inOrder.verify(mTimetableView).setProgressIndicator(false);
        Mockito.verify(mTimetableView).showDepartures(DEPARTURES);
    }
}

But at this line, I get an error:

Mockito.verify(mockTimetableServiceImpl).getTimetable().enqueue(mCallbackArgumentCaptor.capture());

Error says:

java.lang.NullPointerException: Attempt to invoke interface method 'retrofit2.Call retrofit2.Call.clone()' on a null object reference at com.ali.android.sample.timetable.TimetablePresenter.loadDepartures(TimetablePresenter.java:46) 

I can't figure out how to solve it. Do you have any suggestion?

@Override
    public void loadDepartures() {

        mTimetableView.setProgressIndicator(true);

        service.getTimetable().clone().enqueue(new Callback<Flixbus>() {
            @Override
            public void onResponse(Call<Flixbus> call, Response<Flixbus> response) {
                Log.d(TAG, "response is successful :" + response.isSuccessful());
                mTimetableView.setProgressIndicator(false);
                if(response.isSuccessful()) {
                    mTimetableView.showDepartures(response.body().getTimetable().getDepartures());
                } else {
                    Log.d(TAG, "Response Code: " + response.code() + "Message: " + response.message());
                }
            }

            @Override
            public void onFailure(Call<Flixbus> call, Throwable t) {
                mTimetableView.setProgressIndicator(false);
                Log.e(TAG, t.getLocalizedMessage());
            }
        });
    }

Upvotes: 0

Views: 439

Answers (1)

pradithya aria
pradithya aria

Reputation: 687

Have you tried switching the order of verification? Usually mock verification comes after interaction with class under test.

// I believe TimetableService#getTimetable().enqueue(...) is called inside TimetablePresenter#loadDepartures()
mNotesPresenter.loadDepartures();
Mockito.verify(mockTimetableServiceImpl).getTimetable().enqueue(mCallbackArgumentCaptor.capture());

Upvotes: 1

Related Questions