pja*_*e15 5 unit-testing uisearchbar reactive-cocoa swift rx-swift
我已经使用Rxswift一段时间了,并且运行良好。香港专业教育学院设法测试了我所有的代码,但我努力找出如何使用searchbar.rx.bindTo测试搜索。
有很多关于如何使用RxSwift在表视图上搜索和返回结果的教程,但是这些教程都没有向您展示如何对其进行单元测试。 https://www.thedroidsonroids.com/blog/ios/rxswift-by-examples-1-the-basics/
上面的链接显示了我试图用搜索栏并填充TableView想要实现的目标。
香港专业教育学院试图用RxBlocking测试它,但我的测试似乎都死了。systemUnderTest是viewModel结果是从服务返回的Observable <[T]>。
let results = systemUnderTest.results.toBlocking()
let noneObservableList = try! results.single()
//Then
XCTAssert(noneObservableList?.count == expectedCount)
Run Code Online (Sandbox Code Playgroud)
它挂在尝试!result.single()永远不会命中断言。任何人都知道如何测试。
提前致谢。
这是systemUnderTest:
public class SearchViewModel: SearchViewModelContract {
public var query: Variable<String?> = Variable(String.EmptyString())
public var results: Observable<[ThirdPartySite]>
let minimumCharacterCount = 4
let dueTime = 0.3
let disposeBag = DisposeBag()
public init() {
results = Observable.just([Object]())
results = query.asObservable().throttle(dueTime, scheduler: MainScheduler.instance).flatMapLatest{
queryString -> Observable<Object> in
if let queryString = queryString {
if queryString.characters.count >= self.minimumCharacterCount {
return self.Something(siteName: queryString)
}
return Observable.just(Object(in: Object()))
}
return Observable.just(Object(in: Object()))
}.map { results in
return results.items
}.catchErrorJustReturn([Object]()).shareReplay(1)
}
}
Run Code Online (Sandbox Code Playgroud)
我有一些建议:
query并且results都应该是 let,而不是 vars。你永远不应该重置 Observable 类型。这是功能性含义的一部分。debounce更适合。throttle后者更适合触发器。至于您关于如何对搜索进行单元测试的主要问题,我发现RxTest. 以下是生成 searchTerm Observable 的代码以及证明其有效的测试:
extension ObservableType where Element == String? {
func searchTerm(minCharacterCount: Int = 4, dueTime: RxTimeInterval = .milliseconds(300), scheduler: SchedulerType = MainScheduler.instance) -> Observable<String> {
return self
.compactMap { $0 }
.filter { minCharacterCount <= $0.count }
.debounce(dueTime, scheduler: scheduler)
}
}
class Tests: XCTestCase {
var scheduler: TestScheduler!
var result: TestableObserver<String>!
var disposeBag: DisposeBag!
override func setUp() {
super.setUp()
scheduler = TestScheduler(initialClock: 0, resolution: 0.001)
result = scheduler.createObserver(String.self)
disposeBag = DisposeBag()
}
func testExample() {
let input = scheduler.createColdObservable([
.next(1000, Optional.some("")),
.next(2000, Optional.some("xyz")),
.next(3000, Optional.some("wxyz")),
.next(4000, Optional.some("vwxyz")),
.next(4300, Optional.some("uvwxyz"))
])
input
.searchTerm(scheduler: scheduler)
.subscribe(result)
.disposed(by: disposeBag)
scheduler.start()
XCTAssertEqual(result.events, [.next(3300, "wxyz"), .next(4600, "uvwxyz")])
}
}
Run Code Online (Sandbox Code Playgroud)
这些flatMapLatest应该放在你的副作用代码中,那些你不进行单元测试的东西。