Testing ViewModel with RxSwift



我在当前工作的项目中使用ModelView-ViewModel,并使用RxSwiftRxBlocking&RxTests。目前,我正在尝试测试ViewModel,但遇到了很多问题。

假设我的ExampleViewController有一个ExampleViewModel。我的ExampleViewModel期望Observable流,它是来自UITextField的两个流的组合(combineLatest),一个是如果textField是焦点的,另一个是文本流;所以类似CCD_ 11。根据是否聚焦和字符串的上下文,我的ExampleViewModel将向其内部公开的属性发出一个事件,该属性是Observable——UITextField的backgroundColor的状态;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类,并通过控制焦点和文本输入来测试它是否发出正确的UIColor

感谢

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

ExampleViewModel

class ExampleViewModel {
var textFieldColor: Observable<UIColor>
init(
    textFieldText: Observable<String>,
    textFieldFocus: Observable<Bool>,
    validator: TextFieldValidator
) {
    self. textFieldColor = Observable.combineLatest(textFieldText, textFieldFocus) { ($0, $1) }. map { validator.validate($1, text: $0) }
}
}

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