2017-03-01 7 views
0

RxCocoaライブラリからDriverの単体テストを作成しようとしています。ここに私の簡素化の実装コードです:onNextユニットテストRxCocoaドライバが呼び出されない

struct LoginViewModel { 

    var username: Driver<String?>! 
    var password: Driver<String?>! 
    var loginTaps: Driver<Void>! 

    func login() -> Driver<LoginResult> { 
     let credentials = Driver.combineLatest(username, password) { ($0, $1) } 
     let latestCredentials = loginTaps.withLatestFrom(credentials) 

     return latestCredentials.flatMapLatest { (username, password) in 
      .just(.success) 
     } 
    } 
} 

そして、ここで私が通過しようとしてるクイック/軽快なユニットテストです:expect上記

let disposeBag = DisposeBag() 
var capturedLoginResult = LoginResult.failed 

loginViewModel.username = Driver.just("some username") 
loginViewModel.password = Driver.just("some password") 
loginViewModel.loginTaps = Driver.just() 

loginViewModel.login().drive(onNext: { loginResult in 
    capturedLoginResult = loginResult 
}).addDisposableTo(disposeBag) 

expect(capturedLoginResult == .success) 

capturedLoginResultはまだ.failedであることを述べています。テストではreturn latestCredentials.flatMapLatest { (username, password) in .just(.success) }の要素が.drive(onNext:)によって受信されていないように見えます。

loginの実装は、ちょうどの場合:

func login() -> Driver<LoginResult> { 
    return .just(.success) 
} 

テストは合格します。

ここで何が起こっているかについてのご意見はありますか?ありがとう!

+0

テストファイルで 'username'、' password'と 'loginTaps'はどのように設定されていますか? – tomahh

+0

@tomahhこれらは 'username = Driver.just(some username") '、' password = Driver.just( "some password") '、' loginTaps = Driver.just() 'と定義されています。これらの詳細を更新しました! –

答えて

0

Rxのソースは正確にはわかりませんが、使用している演算子がスイッチングスケジューラであると思います。このため、drive(onNext:)で行われたサブスクリプションは即座にトリガーされません。

RxSwiftは、RxTestパッケージを通じて、観測値をテストするための優れたAPIを提供します。あなたはそれを利用するためにあなたのテストを書き換えることができます。

let scheduler = TestScheduler(initialClock: 0) 
let username = scheduler.createHotObservable([next(220, "username"), completed(20)]) 
let password = scheduler.createHotObservable([next(230, "p4ssw0rd"), completed(20)]) 
let loginTaps = scheduler.createHotObservable([next(240), completed(20)]) 

let recordObserver = scheduler.start(300) {() -> Observable<LoginResult> in 
    let loginViewModel = LoginViewModel() 

    loginViewModel.username = username.asDriver(onErrorJustReturn: "") 
    loginViewModel.password = username.asDriver(onErrorJustReturn: "") 
    loginViewModel.loginTaps = loginTaps.asDriver(onErrorJustReturn:()) 

    return loginViewModel.login().asObservable() 
} 

let expectedEvents: [Recorded<Event<LoginResult>>] = [ 
    next(240, Login.success) 
] 

expect(recordObserver.events) == (expectedEvents) 
関連する問題