Подтвердить что ты не робот

IdlingResource Espresso с RxJava

Недавно я преобразовал свое приложение из асинхронных задач в rxjava. Теперь мои тесты на эспрессо больше не ждут завершения моих вызовов данных из-за того, что эспрессо не имеет ресурсов холостого хода для rxjava. Я заметил, что вы можете создавать пользовательские ресурсы бездействия, но я не могу понять, как заставить его работать с rxJava Schedulers, Scheduler.io специально. Любая помощь/наилучшая практика будут очень признательны.

4b9b3361

Ответ 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