RxBlockingを使ってObservableのテストを書く


Observableはテストしにくい?

既存のプログラムをいっぱいObservableに書き換えると、テストが死にます。当たり前ですね。

非同期のものをテストしなきゃいけなくなるわけですが、ちょっとわかりにくいです。
そこで、RxBlockingで同期処理に変換してからテストすると、従来コードからの書き換えも少なくて楽です。
ちょっと書く量が多いだけで、通常のテストと同様にかけます

RxBlocking

Observableをblockして同期処理に変換できます。
実コードには書きたくないですが、テストには楽で良いです。

operator

operatorは4つあります
https://github.com/ReactiveX/RxSwift/blob/master/RxBlocking/BlockingObservable%2BOperators.swift

first()

take(1) をテストする時、すなわち最初にonNextで流れてきた要素をテストする時

let o: Observable<Hoge>
let result: Hoge = try! o.toBlocking().first()!
assertEqual(result, expection)

last()

takeLast(1) をテストする時、すなわちonCompletedが流れてくるまで待ってから、最後にonNextで流れてきた要素をテストする時

let o: Observable<Hoge>
let result: Hoge = try! o.toBlocking().last()!
assertEqual(result, expection)

toArray()

onNextで流れてくる要素をcompletedするまですべて読み込み、配列にします。

let o: Observable<Hoge>
let result: Hoge = try! o.toBlocking().toArray()
assertEqual(result, expection)

single(predicate:_)

single() はonNextで流れてくる要素のうち、predicateを満たすものがただ一つな上でcompletedすることを検証します。

predicateを渡さないときはすべての要素に対してtrueになるので、要素がただ一つであることを検証します。

あくまでcurrentThreadのみブロックする

subscribeOnやobserveOnなどを使うとうまくいかないそうなので注意