我最近将我的应用程序从使用异步任务转换为rxjava。现在,我的espresso测试不再等待我的数据调用完成,因为espresso没有rxjava的空闲资源。我注意到你可以制作自定义空闲资源,但我无法弄清楚如何使它与rxJava Scheduler,Scheduler.io一起使用。任何帮助/最佳实践将不胜感激。
以下是我解决问题的方法:
IdlingResource实现:
public class IdlingApiServiceWrapper implements MyRestService, IdlingResource {
private final MyRestService api;
private final AtomicInteger counter;
private final List<ResourceCallback> callbacks;
public IdlingApiServiceWrapper(MyRestService api) {
this.api = api;
this.callbacks = new ArrayList<>();
this.counter = new AtomicInteger(0);
}
public Observable<MyData> loadData(){
counter.incrementAndGet();
return api.loadData().finallyDo(new Action0() {
@Override
public void call() {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
counter.decrementAndGet();
notifyIdle();
}
});
}
});
}
@Override public String getName() {
return this.getClass().getName();
}
@Override public boolean isIdleNow() {
return counter.get() == 0;
}
@Override public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
callbacks.add(resourceCallback);
}
private void notifyIdle() {
if (counter.get() == 0) {
for (ResourceCallback cb : callbacks) {
cb.onTransitionToIdle();
}
}
}
}
这是我的测试:
public class MyActivityTest extends ActivityInstrumentationTestCase2<MyActivity> {
@Inject
IdlingApiServiceWrapper idlingApiWrapper;
@Override
public void setUp() throws Exception {
//object graph creation
super.setUp();
getActivity();
Espresso.registerIdlingResources(idlingApiWrapper);
}
public void testClickOpenFirstSavedOffer() throws Exception {
onData(is(instanceOf(DataItem.class)))
.atPosition(0)
.perform(click());
}
}
我使用Dagger
进行依赖注入。
在RxJava插件和Espresso之间写了一个小集成片。希望这有助于其他人。
https://gist.github.com/digitalbuddha/d886eae1578bca78b9bf
编辑:
有一种更简单的方法来完成这项任务。将以下规则添加到测试中
public class AsyncTaskSchedulerRule implements TestRule {
final Scheduler asyncTaskScheduler = Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR);
@Override
public Statement apply(Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
RxJavaHooks.setOnIOScheduler(scheduler -> asyncTaskScheduler);
RxJavaHooks.setOnComputationScheduler(scheduler -> asyncTaskScheduler);
RxJavaHooks.setOnNewThreadScheduler(scheduler -> asyncTaskScheduler);
try {
base.evaluate();
} finally {
RxJavaHooks.reset();
}
}
};
}
}
我目前正在使用此实现。它更容易,对我来说效果很好:https://github.com/rosshambrick/RxEspresso