Недавно я преобразовал свое приложение из асинхронных задач в rxjava. Теперь мои тесты на эспрессо больше не ждут завершения моих вызовов данных из-за того, что эспрессо не имеет ресурсов холостого хода для rxjava. Я заметил, что вы можете создавать пользовательские ресурсы бездействия, но я не могу понять, как заставить его работать с rxJava Schedulers, Scheduler.io специально. Любая помощь/наилучшая практика будут очень признательны.
IdlingResource Espresso с RxJava
Ответ 1
Написал небольшую часть интеграции между плагинами RxJava и Espresso. Надеюсь, это поможет кому-то еще.
https://gist.github.com/digitalbuddha/d886eae1578bca78b9bf
Edit:
Существует намного более простой способ выполнить эту задачу. Добавьте в свои тесты следующее правило
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();
}
}
};
}
}
Ответ 2
Вот как я решил проблему:
Реализация 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
для инъекции зависимостей.
Ответ 3
В настоящее время я использую эту реализацию. Это проще и работает для меня до сих пор: https://github.com/rosshambrick/RxEspresso