使用 RxSwift 测试 ViewModel
Posted
技术标签:
【中文标题】使用 RxSwift 测试 ViewModel【英文标题】:Testing ViewModel with RxSwift 【发布时间】:2016-01-06 19:51:37 【问题描述】:我在我目前正在工作的项目中使用ModelView-ViewModel
,并使用RxSwift
、RxBlocking
和RxTests
。目前我正在尝试测试 ViewModel,但在解决这个问题时遇到了很多麻烦。
假设我有一个ExampleViewModel
用于我的ExampleViewController
。我的ExampleViewModel
期待一个Observable
流,它是来自UITextField
的两个流的组合(combineLatest
),一个是textField 是聚焦的,另一个是文本流;所以像Observable<(Bool, String)>
。根据是否聚焦和字符串的上下文,我的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
类并通过控制焦点和文本输入来测试它是否发出正确的UIColor
。
谢谢
【问题讨论】:
【参考方案1】:感谢我同事的建议,我找到了一种更好的方法来构建 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()
【讨论】:
以上是关于使用 RxSwift 测试 ViewModel的主要内容,如果未能解决你的问题,请参考以下文章
在 RxSwift 中使用 Stub 提供程序进行注册验证的 XcTest 案例
在 ViewController 中可观察到的单元测试 RxSwift