swift - onNext 没有被调用单元测试 RxCocoa 驱动程序

标签 swift rx-swift rx-cocoa

我正在尝试为 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) { ($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)

上面的expect表示capturedLoginResult仍然是.failed。似乎 returnlatestCredentials.flatMapLatest { (username,password) in .just(.success) } 中的元素没有被 .drive(onNext: ) 接收在测试中。

如果login的实现只是:

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

测试通过。

对这里发生的事情有什么想法吗?谢谢!

最佳答案

我不知道 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)

关于swift - onNext 没有被调用单元测试 RxCocoa 驱动程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42538423/

相关文章:

swift - 带有 Moya 请求的 RxSwift 顺序平面图

swift - 我如何在 RxSwift 中获取 controlEvent 类型?

ios - RxSwift 在选择时修改表格 View 单元格

swift - 通过泛型函数获取数组中的随机元素

swift - 如何使用 Moya RxSwift 合并 REST 数组

swift - 如何在 Swift 中声明 volatile 变量

ios - 使用 RxSwift 即时更改文本字段的格式

swift - RxSwift 中的 Binder 接受可选的 Any

Swift bool 文字(Obj-C @YES @NO 等价物)

swift - 如何使用下载的属性快速更改 UI