想象一下在MVP模式中,你的演示者订阅了一个返回观察者的服务:
public void gatherData(){
service.doSomeMagic()
.observeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new TheSubscriber());
}
现在类TheSubscriber
从视图调用onNext
的一个方法,说:
@Override public void onNext(ReturnValue value) {
view.displayWhatever(value);
}
现在,在我的单元测试中,我想验证当方法gatherData()
在非错误情况下被调用时,视图的方法displayWhatever(value)
被调用。
:
是否有一个干净的方法来做到这一点?
:
- 我正在使用mockito来验证交互,当然还有更多
- Dagger正在注入除
TheSubscriber
之外的整个演示者
What have I tried:
- 注入订阅者并在测试中模拟它。对我来说看起来有点脏,因为如果我想改变演示者与服务交互的方式(比如不是Rx),那么我需要改变大量的测试和代码。模拟整个服务。这不是很糟糕,但需要我模拟很多方法,我没有完全达到我想要的。
- 在网上查了一下,但似乎没有人有一个干净直接的方法来做这个
Thanks for the help
假设您以类似的方式使用service
和view
的接口:
class Presenter{
Service service;
View view;
Presenter(Service service){
this.service = service;
}
void bindView(View view){
this.view = view;
}
void gatherData(){
service.doSomeMagic()
.observeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(view::displayValue);
}
}
提供模拟来控制和验证行为是可能的:
@Test void assert_that_displayValue_is_called(){
Service service = mock(Service.class);
View view = mock(View.class);
when(service.doSomeMagic()).thenReturn(Observable.just("myvalue"));
Presenter presenter = new Presenter(service);
presenter.bindView(view);
presenter.gatherData();
verify(view).displayValue("myvalue");
}
我知道这很晚了,但可能会帮助别人,因为我搜索了很长时间的解决方案,你的问题:D
对于我来说,它成功地添加了一个Observable.Transformer<T, T>
如下:
void gatherData() {
service.doSomeMagic()
.compose(getSchedulerTransformer())
.subscribe(view::displayValue);
}
private <T> Observable.Transformer<T, T> getSchedulerTransformer() {
if (mTransformer == null) {
mTransformer = (Observable.Transformer<T, T>) observable -> observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
return mTransformer;
}
void setSchedulerTransformer(Observable.Transformer<Observable<?>, Observable<?>> transformer) {
mTransformer = transformer;
}
要设置Transformer我只需要传递这个:
setSchedulerTransformer(observable -> {
if (observable instanceof Observable) {
Observable observable1 = (Observable) observable;
return observable1.subscribeOn(Schedulers.immediate())
.observeOn(Schedulers.immediate());
}
return null;
});
所以只需在测试中添加@Before
方法并调用presenter.setSchedulerTransformer
,它应该能够测试这个:)