所以我有问题,这是我的演示者代码:
@Override
public void login(String phone, String password) {
loginView.showProgress();
compositeSubscription.clear();
Subscription subscription = service.login(phone,password)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(data -> {
//Log.d("Login", new Gson().toJson(data));
loginView.hideProgress();
if(data.getSt()==1)
{
saveDataPartner(data.getData().getId_hos(), data.getData().getName(), data.getData().getEmail(), data.getData().getPhone(), data.getData().getAvatar());
loginView.navigateToMainMenu();
}
else {
loginView.showMessage(data.getMsg());
}
}, error -> {
loginView.hideProgress();
loginView.showMessage(ErrorUtils.getErrorMessage(error));
});
}
我想用这段代码测试一下:
@Before
public void setUp() throws Exception {
RxAndroidPlugins.getInstance().registerSchedulersHook(new RxAndroidSchedulersHook() {
@Override
public Scheduler getMainThreadScheduler() {
return Schedulers.immediate();
}
});
}
@After
public void tearDown() {
RxAndroidPlugins.getInstance().reset();
}
@Test
public void clickBtnLogin() {
User user = new User();
user.setName("aa");
ResultAPIUser<User> ru = new ResultAPIUser<User>();
ru.setData(user);
ru.setMsg("example message");
ru.setSt(1);
when(service.login("aa","aa")).thenReturn(Observable.just(ru));
loginPresenter.login("aa","aa");
verify(loginView).showProgress();
verify(loginView).hideProgress();
verify(loginView).navigateToMainMenu();
}
所以我设置st的值是1,我认为应该没问题。但我明白了:
Wanted but not invoked:
loginView.hideProgress();
-> at hos.wellhos.com.hosapps.login.LoginPresenterTest.clickBtnLogin(LoginPresenterTest.java:79)
However, there were other interactions with this mock:
loginView.setPresenter(
hos.wellhos.com.hosapps.login.LoginPresenter@4313f5bc
);
-> at hos.wellhos.com.hosapps.login.LoginPresenter.<init> (LoginPresenter.java:43)
任何人都可以帮我解决这个问题,我认为这有一个棘手的问题吗?
答案 0 :(得分:0)
这可能是一个线程问题。您的Observable
订阅了Schedulers.io
即使你然后切换到主线程,所以处理结果这将花费时间。因此,在订阅完成之前,您的验证语句正在处理中。
有几种方法可以解决这个问题:
动态调度程序
而不是将所需的计划程序直接传递到subscribeOn
&amp; observeOn
方法可以定义为您保存这些变量的成员变量:
Scheduler ioScheduler;
Scheduler mainThreadScheduler;
并在observeOn
/ subscribeOn
声明中使用它们:
.subscribeOn(ioScheduler)
.observeOn(mainThreadScheduler)
然后,您可以在类构造函数中执行任何其他依赖项时设置它们。对于生产代码,您可以将它们设置为正常Schedulers.io()
&amp; AndroidSchedulers.mainThread()
但是在您的测试代码中,您可以将它们都设置为Schedulers.immediate()
(它只返回当前线程的调度程序)。
<强> RxJavaHooks 强>
在RxJava 1.1.7中引入了一个名为RxJavaHooks
的util类,它允许您挂钩到RxJava生命周期的几个部分。其中一个钩子是setOnIOScheduler()
方法。这样您就可以更改Scheduler
返回的Schedulers.io
。
在您的情况下,您想将其更改为Schedulers.immediate()
:
RxJavaHooks.setOnIOScheduler(scheduler -> Schedulers.immediate());
完成测试后,您需要致电:
RxJavaHooks.reset();
这只会使一切恢复正常,这样这种变化不会干扰您在其他地方运行的其他测试。