验证 rxjava 订阅者中的交互
Verify interactions in rxjava subscribers
想象一下 MVP 模式中的情况,您的演示者订阅返回观察者的服务:
public void gatherData(){
service.doSomeMagic()
.observeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new TheSubscriber());
}
现在 class TheSubscriber
从视图调用 onNext
一个方法,比如:
@Override public void onNext(ReturnValue value) {
view.displayWhatever(value);
}
现在,在我的单元测试中,我想验证当方法 gatherData()
在非错误情况下被调用时,视图的方法 displayWhatever(value)
被调用。
问题:
有干净的方法吗?
背景:
- 我正在使用 mockito 来验证交互,当然还有更多
- Dagger 正在注入除
TheSubscriber
之外的整个演示者
我尝试了什么:
- 注入订阅者并在测试中模拟它。对我来说看起来有点脏,因为如果我想改变演示者与服务交互的方式(说不是 Rx),那么我需要改变很多测试和代码。
- 模拟整个服务。这还不错,但是需要我模拟很多方法,但我并没有完全达到我想要的效果。
- 在互联网上查了一下,但似乎没有人有一个干净直接的方法来做到这一点
感谢您的帮助
假设您以类似的方式使用 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
它应该能够测试这个:)
希望这会有所帮助并且可以理解 :D
想象一下 MVP 模式中的情况,您的演示者订阅返回观察者的服务:
public void gatherData(){
service.doSomeMagic()
.observeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new TheSubscriber());
}
现在 class TheSubscriber
从视图调用 onNext
一个方法,比如:
@Override public void onNext(ReturnValue value) {
view.displayWhatever(value);
}
现在,在我的单元测试中,我想验证当方法 gatherData()
在非错误情况下被调用时,视图的方法 displayWhatever(value)
被调用。
问题:
有干净的方法吗?
背景:
- 我正在使用 mockito 来验证交互,当然还有更多
- Dagger 正在注入除
TheSubscriber
之外的整个演示者
我尝试了什么:
- 注入订阅者并在测试中模拟它。对我来说看起来有点脏,因为如果我想改变演示者与服务交互的方式(说不是 Rx),那么我需要改变很多测试和代码。
- 模拟整个服务。这还不错,但是需要我模拟很多方法,但我并没有完全达到我想要的效果。
- 在互联网上查了一下,但似乎没有人有一个干净直接的方法来做到这一点
感谢您的帮助
假设您以类似的方式使用 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
它应该能够测试这个:)
希望这会有所帮助并且可以理解 :D