[英]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.