IdlingResource Espresso with RxJava

后端 未结 3 1297
没有蜡笔的小新
没有蜡笔的小新 2021-02-04 09:21

I recently converted my application from using async tasks to rxjava. Now, my espresso tests no longer wait for my data calls to complete due to espresso not having an idling r

相关标签:
3条回答
  • 2021-02-04 10:02

    Here is how I solved the problem:

    IdlingResource implementation:

    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();
            }
        }
       }
       }
    

    and here is my test:

    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());
       }
      }
    

    I used Dagger for dependency injection.

    0 讨论(0)
  • 2021-02-04 10:04

    Wrote a little integration piece between RxJava Plugins and Espresso. Hope this helps someone else.

    https://gist.github.com/digitalbuddha/d886eae1578bca78b9bf

    Edit:

    There is a much easier way to accomplish this task. Add the following rule to your tests

    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();
                    }
                }
            };
        }
    }
    
    0 讨论(0)
  • 2021-02-04 10:09

    I am currently using this implementation. Its easier and works very well for me so far: https://github.com/rosshambrick/RxEspresso

    0 讨论(0)
提交回复
热议问题