2016-11-26 19 views
0

ボタンがあるとします。ユニットテストマルチスレッドAndroid RxJava

ボタンをクリックすると、それを無効に(mainThreadスレッド)は、データをロードするバックグラウンドタスク(IOスレッド)を開始します。データが読み込まれると、ボタンが有効になります(mainThreadスレッド)。

即時にスケジューラを変更するのが一般的ですが、これは私のケースでは機能しません。ボタンのクリックはバックグラウンドタスクが完了するまでブロックされません。それはバックグラウンドタスクを開始した後です。

単体テスト以外にも、機能的なエスプレッソテストでこれをテストしたいと思います。

このマルチスレッドRxJavaのケースをテストするにはどうすればよいですか?

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

あなたも行くことができます:

答えて

0

あなたがこのスケジューラを使用して、新しいスレッドが必要なときにプラスと呼ばれる取得をメインキューをブロックすることはできません、今

ThreadFactory custom = new CustomThreadFactory(); 
ExecutorService executorService = Executors.newCachedThreadPool(custom); //or use newSingleThreadExecutor(..) 
Scheduler customScheduler = Schedulers.from(executorService); 

独自のThreadFactory書くことができますさらに新しいスレッドを装備する -

class CustomThread extends Thread { 
    public CustomThread(Runnable r) { 
     super(r); 
    } 
    @Override 
    public void run() { 
     System.out.printf("About to run!"); 
     super.run(); 
    } 
    } 
} 
0

RxUtil

1)。RxUtildefault implementationをコンストラクタまたはDIを介して提供する。

2)。あなたの代わりに直接スケジューラを適用し、あなたに観察を作成

.subscribeOn(Schedulers.newThread()) 
    .observeOn(AndroidSchedulers.mainThread()) 

使用RxUtil

.compose(rxUtil.applySchedulers()) 

例:

https://github.com/DAYTeam/GoEnglish/blob/master/app/src/main/java/ru/goenglish/goenglish/services/impl/ScheduleServiceImpl.java#L38-L44

3)。ユニットテストで、代わり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

その結果、すべてのテストは、1つのスレッドで実行され、アプリケーションには、異なる執行

上で実行されます