[英]How unit test multithreaded Android RxJava
假设有一个按钮。
单击该按钮将禁用它( mainThread线程),启动后台任务以加载数据( IO线程)。 加载数据后,按钮被启用( mainThread线程)。
对于测试,通常将调度程序更改为立即 ,但这在我的情况下不起作用 - 按钮单击将阻止直到完成后台任务,我将永远无法检查按钮在启动后台任务后是否被禁用。
除了单元测试,我还想在功能性Espresso测试中测试它。
我如何测试这个多线程RxJava案例?
你可以编写自己的ThreadFactory
ThreadFactory custom = new CustomThreadFactory();
ExecutorService executorService = Executors.newCachedThreadPool(custom); //or use newSingleThreadExecutor(..)
Scheduler customScheduler = Schedulers.from(executorService);
现在你可以使用这个调度程序,而不是阻止主队列加上在需要新线程时调用:
class CustomThreadFactory implements ThreadFactory {
public Thread lastT;
public int newThreadCounter = 0;
@Override
public Thread newThread(Runnable r) {
newThreadCounter++;
System.out.println("newThread called");
Thread lastT = new Thread(r); //or CustomThread(r)
return lastT;
}
}
您甚至可以进一步检测新线程 -
class CustomThread extends Thread {
public CustomThread(Runnable r) {
super(r);
}
@Override
public void run() {
System.out.printf("About to run!");
super.run();
}
}
}
我建议你使用RxUtil
1)。 通过构造函数或DI提供RxUtil
默认实现
2)。 创建observable时,而不是直接应用调度程序:
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
使用RxUtil
:
.compose(rxUtil.applySchedulers())
例:
3)。 在单元测试中,创建RxUtil
版本而不是RxUtil
的默认实现:
public class UnitTestRxUtil implements RxUtil {
@Override
public <T> Observable.Transformer<T, T> applySchedulers() {
return observable -> observable.subscribeOn(Schedulers.immediate())
.observeOn(Schedulers.immediate());
}
}
链接: https : //github.com/DAYTeam/GoEnglish/blob/master/app/src/test/java/ru/goenglish/goenglish/util/UnitTestRxUtil.java
4)。 通过构造函数或DI传递此实现。
示例(构造函数): https : //github.com/DAYTeam/GoEnglish/blob/master/app/src/test/java/ru/goenglish/goenglish/ScheduleServiceImplTest.java#L45
因此,所有测试都将在一个线程中执行,而在应用程序中,它将在不同的执行程序上执行
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.