A-Zaiats
4/22/2017 - 3:43 PM

RxJunitRule

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

import java.util.concurrent.Callable;

import io.reactivex.Scheduler;
import io.reactivex.android.plugins.RxAndroidPlugins;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Function;
import io.reactivex.plugins.RxJavaPlugins;
import io.reactivex.schedulers.Schedulers;

public class RxJunitRule implements TestRule {

    private final Function<Scheduler, Scheduler> handler = new Function<Scheduler, Scheduler>() {
        @Override
        public Scheduler apply(@NonNull Scheduler scheduler) throws Exception {
            return Schedulers.trampoline();
        }
    };
    
    private final Function<Callable<Scheduler>, Scheduler> androidInitHandler = new Function<Callable<Scheduler>, Scheduler>() {
        @Override
        public Scheduler apply(@NonNull Callable<Scheduler> schedulerCallable) throws Exception {
            return Schedulers.trampoline();
        }
    };
    
    @Override
    public Statement apply(final Statement base, Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                clearHooks();
                applyTestHooks();
                base.evaluate();
                clearHooks();
            }
        };
    }
    
    private void clearHooks() {
        RxJavaPlugins.reset();
        RxAndroidPlugins.reset();
    }
    
    private void applyTestHooks() {
        RxJavaPlugins.setComputationSchedulerHandler(handler);
        RxJavaPlugins.setIoSchedulerHandler(handler);
        RxJavaPlugins.setNewThreadSchedulerHandler(handler);
        RxAndroidPlugins.setMainThreadSchedulerHandler(handler);
        RxAndroidPlugins.setInitMainThreadSchedulerHandler(androidInitHandler);
    }
}