onNext 没有被调用单元测试 RxCocoa 驱动程序
onNext not getting called unit testing RxCocoa Driver
我正在尝试从 RxCocoa 库为 Driver
编写单元测试。这是我的简化实现代码:
struct LoginViewModel {
var username: Driver<String?>!
var password: Driver<String?>!
var loginTaps: Driver<Void>!
func login() -> Driver<LoginResult> {
let credentials = Driver.combineLatest(username, password) { ([=10=], ) }
let latestCredentials = loginTaps.withLatestFrom(credentials)
return latestCredentials.flatMapLatest { (username, password) in
.just(.success)
}
}
}
这是我试图通过的 Quick/Nimble 单元测试:
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)
上面expect
说capturedLoginResult
仍然是.failed
。似乎来自 return latestCredentials.flatMapLatest { (username, password) in .just(.success) }
的元素在测试中未被 .drive(onNext: )
接收。
如果login
的执行就是:
func login() -> Driver<LoginResult> {
return .just(.success)
}
测试通过。
对这里发生的事情有什么想法吗?谢谢!
我不知道在 Rx 的源代码中的确切位置,但我猜你正在使用的操作员正在切换调度程序。因此,使用 drive(onNext:)
进行的订阅不会立即触发。
RxSwift 通过 RxTest
包提供了一个很好的 API 来测试我们的 observables。您可以重写测试以利用它。
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)
我正在尝试从 RxCocoa 库为 Driver
编写单元测试。这是我的简化实现代码:
struct LoginViewModel {
var username: Driver<String?>!
var password: Driver<String?>!
var loginTaps: Driver<Void>!
func login() -> Driver<LoginResult> {
let credentials = Driver.combineLatest(username, password) { ([=10=], ) }
let latestCredentials = loginTaps.withLatestFrom(credentials)
return latestCredentials.flatMapLatest { (username, password) in
.just(.success)
}
}
}
这是我试图通过的 Quick/Nimble 单元测试:
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)
上面expect
说capturedLoginResult
仍然是.failed
。似乎来自 return latestCredentials.flatMapLatest { (username, password) in .just(.success) }
的元素在测试中未被 .drive(onNext: )
接收。
如果login
的执行就是:
func login() -> Driver<LoginResult> {
return .just(.success)
}
测试通过。
对这里发生的事情有什么想法吗?谢谢!
我不知道在 Rx 的源代码中的确切位置,但我猜你正在使用的操作员正在切换调度程序。因此,使用 drive(onNext:)
进行的订阅不会立即触发。
RxSwift 通过 RxTest
包提供了一个很好的 API 来测试我们的 observables。您可以重写测试以利用它。
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)