追記 @ 11/18
第3回RxSwift勉強会 でこの記事を元ネタに発表しました。
下記がその時に使ったスライドです。
https://speakerdeck.com/tasanobu/rxtestru-men
RxTestとは
-
RxTest
はRxSwift
本体とは分離されたテスト用フレームワーク - 便利なテスト用クラスが用意されている(後述)
- Cocoapodsで利用可能。
/// Add `RxTest` to a test target
target 'SampleTests' do
pod 'RxSwift'
pod 'RxTests'
end
主なクラス
RxTest
では実時間とは異なる 仮想時間
に基づきイベントを発生させる仕組みとなっています。主に次のクラスを使用してテストを書きます。
TestScheduler
- 仮想時間に基づいてイベントを発生させることができるスケジューラ。
- 仮想時刻を指定して任意アクションを実行
-
TestableObservable
TestableObserver
のファクトリメソッドを持つ
TestableObservable
- 仮想時間にイベントが発生するObservable
TestableObserver
- 受信したイベントを仮想時間とともに保持するObserver
利用例
上記のクラスの説明ではいまいちピンとこないと思います。
RxSwift の mapオペレータのテスト を簡素化したコードを例にして説明します。
func testMap() {
// 仮想時刻 0 を指定しTestSchedulerを生成
let scheduler = TestScheduler(initialClock: 0)
// TestableObserver<Int> を `仮想時刻` `値` を指定して生成
let xs = scheduler.createHotObservable([
next(150, 1),
next(210, 0),
next(240, 4),
completed(300)
])
// TestableObserver<Int> を生成
let observer = scheduler.createObserver(Int.self)
// 仮想時刻 `200` に `observer` を `xs` に subscribe させる
scheduler.scheduleAt(200) {
xs.map { $0 * 2 }
.subscribe(observer)
.addDisposableTo(disposeBag)
}
// schedulerを開始
scheduler.start()
/// TestableObserver が受信したイベントを検証
let expectedEvents = [
next(210, 0 * 2),
next(240, 4 * 2),
completed(300)
]
XCTAssertEqual(observer.events, expectedEvents)
/// TestableObservable が subscribe/unsubscribe された仮想時刻を検証
let expectedSubscriptions = [
Subscription(200, 300)
]
XCTAssertEqual(xs.subscriptions, expectedSubscriptions)
}
まとめ
RxTestの概要とテストコード例をまとめてみました。
RxSwiftのテストを書くのは面倒かと思っていましたが、RxTestを使うと意外にシンプルにかけるな〜という印象です。