使用改造时进行单元测试

时间:2018-04-08 13:18:36

标签: android mockito retrofit2

我有以下服务界面进行改造:

public interface TimetableService {

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

我想在改装之后测试用户界面:

@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);
    }
}

但在这一行,我收到一个错误:

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

错误说:

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) 

我无法弄清楚如何解决它。你有什么建议吗?

@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());
            }
        });
    }

1 个答案:

答案 0 :(得分:1)

您是否尝试过切换验证顺序?通常模拟验证是在与被测试的类进行交互之后进行的。

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