我正在使用改造来开发基于MVP模式的应用程序来执行网络连接。我想对我的演示者进行单元测试,但它失败了。
在我的app中,dataView实现了由Mockito模拟的DataView
。在
DataPresenter
方法onViewCreated
实例中的MyApi
来自MyApplication
并执行请求。匿名Subscriber<Data>
onNext在showData(Data data)
上调用dataView
。不幸的是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());
}
测试失败&#34;想要但未被调用: dataView.showData(...&#34;。
有趣的Response execute()
在MockClient
中被调用,但onNext(Data data)
中包含的订阅者DataPresenterImpl
则没有。有任何想法吗?我想这是请求异步的问题。
答案 0 :(得分:0)
问题在于工作正在被发送到另一个线程并且无法验证最新情况。我的解决方案是创建一个调度程序工厂并将其模拟出来并返回主线程进行测试 像这些。类似的东西:
public class schedulerFactory {
public Scheduler io() {
return Schedulers.io();
}
//etc
}
然后在你的测试中你会写这样的东西:
@Mock SchedulerFactory factory
@Before
public void setUp() {
when(factory.io()).thenReturn(Schedulers.mainThread());
}
一般来说,最好在同一个线程中运行所有代码进行测试