2017-03-01 17 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) 
     } 
    } 
} 

而这里的快速/灵活的单元测试,我试图通过:

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) 

以上expectcapturedLoginResult仍然.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(“某个密码”)'和'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) 
相关问题