Sha*_*ave 5 unit-testing ios swift rx-swift
我对RxSwift很陌生。我有一个具有预输入/自动完成功能的视图控制器(即,UITextField中的用户类型,并且只要他们输入至少2个字符,就会发出网络请求以搜索匹配建议)。控制器viewDidLoad调用以下方法来设置Observable:
class TypeaheadResultsViewController: UIViewController {
var searchTextFieldObservable: Observable<String>!
@IBOutlet weak var searchTextField: UITextField!
private let disposeBag = DisposeBag()
var results: [TypeaheadResult]?
override func viewDidLoad() {
super.viewDidLoad()
//... unrelated setup stuff ...
setupSearchTextObserver()
}
func setupSearchTextObserver() {
searchTextFieldObservable =
self.searchTextField
.rx
.text
.throttle(0.5, scheduler: MainScheduler.instance)
.map { $0 ?? "" }
searchTextFieldObservable
.filter { $0.count >= 2 }
.flatMapLatest { searchTerm in self.search(for: searchTerm) }
.subscribe(
onNext: { [weak self] searchResults in
self?.resetResults(results: searchResults)
},
onError: { [weak self] error in
print(error)
self?.activityIndicator.stopAnimating()
}
)
.disposed(by: disposeBag)
// This is the part I want to test:
searchTextFieldObservable
.filter { $0.count < 2 }
.subscribe(
onNext: { [weak self] _ in
self?.results = nil
}
)
.disposed(by: disposeBag)
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎工作正常,但是我正在努力找出如何对的行为进行单元测试searchTextFieldObservable。为简单起见,我只想通过单元测试来验证将results设置为nilwhen searchTextField更改事件后少于2个字符的时间。
我尝试了几种不同的方法。我的测试目前看起来像这样:
class TypeaheadResultsViewControllerTests: XCTestCase {
var ctrl: TypeaheadResultsViewController!
override func setUp() {
super.setUp()
let storyboard = UIStoryboard(name: "MainStoryboard", bundle: nil)
ctrl = storyboard.instantiateViewController(withIdentifier: "TypeaheadResultsViewController") as! TypeaheadResultsViewController
}
override func tearDown() {
ctrl = nil
super.tearDown()
}
/// Verify that the searchTextObserver sets the results array
/// to nil when there are less than two characters in the searchTextView
func testManualChange() {
// Given: The view is loaded (this triggers viewDidLoad)
XCTAssertNotNil(ctrl.view)
XCTAssertNotNil(ctrl.searchTextField)
XCTAssertNotNil(ctrl.searchTextFieldObservable)
// And: results is not empty
ctrl.results = [ TypeaheadResult(value: "Something") ]
let tfObservable = ctrl.searchTextField.rx.text.subscribeOn(MainScheduler.instance)
//ctrl.searchTextField.rx.text.onNext("e")
ctrl.searchTextField.insertText("e")
//ctrl.searchTextField.text = "e"
do {
guard let result =
try tfObservable.toBlocking(timeout: 5.0).first() else {
return }
XCTAssertEqual(result, "e") // passes
XCTAssertNil(ctrl.results) // fails
} catch {
print(error)
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,我想知道如何手动/以编程方式在searchTextFieldObservable(或最好在searchTextField)上触发事件,以触发第二个订阅中标记为“这是我要测试的部分:”的代码。
问题是self.ctrl.searchTextField.rx.text.onNext("e")不会触发searchTextFieldObservable onNext订阅。
如果像这样直接设置文本值,也不会触发订阅self.ctrl.searchTextField.text = "e"。
如果您像这样设置 textField 值,订阅将触发(并且您的测试应该成功)self.ctrl.searchTextField.insertText("e")。
我认为这样做的原因是UITextField.rx.text观察来自 的方法UIKeyInput。
| 归档时间: |
|
| 查看次数: |
1014 次 |
| 最近记录: |