我正在开发基于mvp模式的应用程序,使用改进来执行联网。我想对演示者进行单元测试,但失败了。
在我的应用程序中,dataview实现了mockito模拟的DataView。在
DataPresenter方法中的onViewCreated实例从MyApi获取并执行请求。匿名onnext调用MyApplicationonSubscriber<Data>。不幸的是showData(Data data)没有通过测试。我自嘲改造客户以确定的方式响应。
代码如下:

public class DataFragment extends ProgressFragment implements DataView {

    protected DataPresenter mDataPresenter;

    //[...] initialization arguments boilerplate etc.


    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mDataPresenter.onViewCreated(mId);
        //[...]
    }

    @Override
    public void startLoading() {
        setContentShown(false);
    }

    @Override
    public void stopLoading() {
        setContentShown(true);
    }

    @Override
    public void showData(Data data) {
        setContentEmpty(false);
        //[...] present data
    }

    @Override
    public void showError() {
        setContentEmpty(true);
        setEmptyText(R.string.unknown_error);
    }
}

dataView
@Override
public void onViewCreated(long id) {
    getView().startLoading();
    MyApplication.getInstance().getMyApi().checkIn(User.getUser().getFormattedTokenForRequest(),
            (int) id).observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()).subscribe(new Subscriber<Data>() {
        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {
            getView().showError();
            getView().stopLoading();
        }

        @Override
        public void onNext(Data data) {
            getView().showData(data);
            getView().stopLoading();

        }
    });
    ;
}

我的测试用例:
    public static final String GOOD_RESPONSE = "[Data in JSON]"
    public static final int GOOD_STATUS = 201;

    @Mock
    DataView mDataView;

    @Mock
    MyApplication app;

    @Mock
    SharedPreferencesManager mSharedPreferencesManager;

    DataPresenter mDataPresenter;

    @Before
    public void setUp() throws Exception {
        mDataPresenter = new DataPresenterImpl(mDataView);
        MyApplication.setInstance(app);
        Mockito.when(app.getSharedPreferencesManager()).thenReturn(mSharedPreferencesManager);
        Mockito.when(mSharedPreferencesManager.getUser()).thenReturn(null);
    }

    @Test
    public void testCase() throws Exception {
        RestAdapter adapter = (new RestAdapter.Builder()).setEndpoint(URL)
                .setClient(new MockClient(GOOD_RESPONSE, GOOD_STATUS))
                .build();
        Mockito.when(app.getMyApi()).thenReturn(adapter.create(MyApi.class));
        mCheckInPresenter.onViewCreated(3);
        Mockito.verify(checkInView).startLoading();
        Mockito.verify(checkInView).showData(new Data());
    }

在“需要但未调用:
dataview.showdata(…)。
有趣的Mockito.verify(dataView).showData(data)是在DataPresenter中调用的,但Response execute()中包含的订户中的MockClient不是。有什么想法吗?我想这是请求异步的问题。

最佳答案

问题是工作被发送到另一个线程,mockito无法验证发生了什么。我的解决方案是创建一个调度程序工厂并模拟它并返回主线程进行测试
像这样。类似于:

public class schedulerFactory {

public Scheduler io() {
 return Schedulers.io();
}
 //etc
}

然后在你的测试中你会写这样的东西:
@Mock SchedulerFactory factory

@Before
public void setUp() {
 when(factory.io()).thenReturn(Schedulers.mainThread());

}

一般来说,在同一个线程中运行所有代码进行测试是一个好主意

07-24 09:48
查看更多