使用 RxSwift 测试 ViewModel
Testing ViewModel with RxSwift
我在我目前工作的项目中使用 ModelView-ViewModel
,并使用 RxSwift
、RxBlocking
和 RxTests
。目前我正在尝试测试 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()
}
}
}
我在我目前工作的项目中使用 ModelView-ViewModel
,并使用 RxSwift
、RxBlocking
和 RxTests
。目前我正在尝试测试 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()
}
}
}