我正在开发基于MVP模式的应用程序,使用改进来执行网络。我想对我的演示者进行单元测试,但它失败了。
在我的应用程序中,dataView实现了被Mockito嘲笑的DataView
。在里面onViewCreated
方法中的DataPresenter
MyApi
实例是从MyApplication
中获取的,它执行请求。匿名Subscriber<Data>
onNext调用dataView
上的showData(Data data)
。不幸的是,Mockito.verify(dataView).showData(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);
}
}
在DataPresenter
:中
@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());
}
在"Wanted but not invoked:dataView.showData(…".
感兴趣的Response execute()
在MockClient
中被调用,而包括在DataPresenterImpl
中的订户中的onNext(Data data)
不是。有什么想法吗?我想这是请求异步的问题。
问题是工作被发送到另一个线程,mockito无法验证发生了什么。我的解决方案是创建一个调度器工厂,模拟它并返回主线程进行测试就像这些。类似于:
public class schedulerFactory {
public Scheduler io() {
return Schedulers.io();
}
//etc
}
然后在你的测试中,你会写这样的东西:
@Mock SchedulerFactory factory
@Before
public void setUp() {
when(factory.io()).thenReturn(Schedulers.mainThread());
}
一般来说,在同一个线程中运行所有代码来测试