使用 RxSwift 测试 ViewModel

Testing ViewModel with RxSwift

我在我目前工作的项目中使用 ModelView-ViewModel,并使用 RxSwiftRxBlockingRxTests。目前我正在尝试测试 ViewModel,但在解决这个问题时遇到了很多麻烦。

所以假设我的 ExampleViewController 有一个 ExampleViewModel。我的 ExampleViewModel 期待一个 Observable 流,它是来自 UITextField 的两个流的组合 (combineLatest),一个是如果 textField 被聚焦,另一个是流文字;所以像 Observable<(Bool, String)>。根据是否聚焦和字符串的上下文,my ExampleViewModel 将向其内部暴露的 属性 发出一个事件,这是 Observable UITextField 的背景颜色的状态; Observable<UIColor>

ExampleViewModel.swift :

class ExampleViewModel {

private let disposeBag = DisposeBag()

private let _textFieldColor: PublishSubject<UIColor>
var textFieldColor: Observable<UIColor> { get { return self._textFieldColor.asObservable() } }

init(textFieldObservable: Observable<(Bool, String)>) {
    textFieldObservable.subscribeNext { (focus, text) in
        self.validateTextField(focus, text: text)
    }.addDisposableTo(self.disposeBag)
}

func validateTextField(focus: Bool, text: String) {
    if !focus && !text.isEmpty {
        self._textFieldColor.onNext(UIColor.whiteColor())
    } else {
        self._textFieldColor.onNext(UIColor.redColor())
    }
}
}

(抱歉,我不知道如何正确格式化)

基本上我想测试 ExampleViewModel class 并通过控制焦点和文本输入来测试它是否发出正确的 UIColor

谢谢

感谢我同事的建议,我找到了构建 ExampleViewModel 可测试性的更好方法。通过使用 ExampleViewModel 分离验证方法并使用 map 运算符设置 textFieldColor Observable,其中使用了验证器,验证是在外部完成的,不使用 Rx 简化逻辑测试。

示例视图模型

class ExampleViewModel {

var textFieldColor: Observable<UIColor>

init(
    textFieldText: Observable<String>,
    textFieldFocus: Observable<Bool>,
    validator: TextFieldValidator
) {
    self. textFieldColor = Observable.combineLatest(textFieldText, textFieldFocus) { ([=10=], ) }. map { validator.validate(, text: [=10=]) }
}
}



 class TextFieldValidator {

func validate(focus: Bool, text: String) -> UIColor {
    if !focus && !text.isEmpty {
        return UIColor.whiteColor()
    } else {
        return UIColor.redColor()
    }
}
}