假設有一個按鈕。單元測試多線程Android RxJava
點擊按鈕禁用它(mainThread線程),啓動後臺任務來加載數據(IO線程)。數據加載完成後,該按鈕將啓用(mainThread線程)。
對於測試,這是常見的改變調度到立即,但這不會在我的情況下工作 - 按一下按鈕將阻塞,直到後臺任務完成,我就永遠無法檢查按鈕被禁用在它開始後臺任務之後。
除了單元測試,我還想在功能性的Espresso測試中進行測試。
如何測試此多線程RxJava案例?
假設有一個按鈕。單元測試多線程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)。通過構造函數提供default implementation的RxUtil
或DI
2)。當你創建你的觀察到的,而不是直接應用調度,:
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
使用RxUtil
:
.compose(rxUtil.applySchedulers())
例子:
3)。在單元測試,而不是RxUtil
默認的實現,創造嘲笑版:
public class UnitTestRxUtil implements RxUtil {
@Override
public <T> Observable.Transformer<T, T> applySchedulers() {
return observable -> observable.subscribeOn(Schedulers.immediate())
.observeOn(Schedulers.immediate());
}
}
4)。通過構造函數或DI傳遞此實現。
實施例(構造):https://github.com/DAYTeam/GoEnglish/blob/master/app/src/test/java/ru/goenglish/goenglish/ScheduleServiceImplTest.java#L45
其結果是,所有的試驗中,將在一個線程中執行,並且在應用程序中,它會在不同的執行器
執行