我正在开发基于mvp模式的应用程序,使用改进来执行联网。我想对演示者进行单元测试,但失败了。
在我的应用程序中,dataview实现了mockito模拟的DataView
。在DataPresenter
方法中的onViewCreated
实例从MyApi
获取并执行请求。匿名onnext调用MyApplication
onSubscriber<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());
}
一般来说,在同一个线程中运行所有代码进行测试是一个好主意