import XCTest import RxSwift import RxTest @testable import TestDemo class TestDemoTests: XCTestCase { var scheduler: TestScheduler! //scheduler是TestScheduler的实例,将被用于每一次测试 var subscription: Disposable! //subscription将持有你每次测试的订阅 override func setUp() { super.setUp() //1 scheduler = TestScheduler(initialClock: 0) } override func tearDown() { //2 scheduler.scheduleAt(1000) { self.subscription.dispose() } super.tearDown() } } 注意:setUp()方法在每次开始测试之前会被调用,这是单元测试的基本内容,想了解unit-test,可以看这里。 1:使用TestScheduler的初始化方法创建scheduler实例,指定initialClock为0,这表示你想在测试的开始时测试scheduler 2:tearDown在每次测试完成后被调用。在该方法里面,你的调度者(scheduler)将处理测试订阅者在1000毫秒的时候。注意:我们所写的测试每次运行都会少于一秒,所以这里在1秒的时候处理测试的订阅者(test’s subscription)的安全的。 5: 现在开始,写几个简单例子。测试amb操作符。我们在组合操作符中学习了amb,对于两个或者多个观察者序列,仅仅只有最先发送消息的观察者序列才能被订阅者监听。并且之后只有该序列发送消息有效。
//1: func testAmb() { //2: let observer = scheduler.createObserver(String.self) //3: let observableA = scheduler.createHotObservable([ //4: next(100,"a)"), next(200,"b)"), next(300,"c)") ]) //5: let observableB = scheduler.createHotObservable([ next(90,"1)"), next(200,"2)"), next(300,"3)") ]) //6: let ambObservable = observableA.amb(observableB) //7: scheduler.scheduleAt(0) { //8: self.subscription = ambObservable.subscribe(observer) } //9: scheduler.start() //10: let results = observer.events.map { $0.value.element! } //11: XCTAssertEqual(results, ["1)","2)","3)"]) //ok } 分析: 1:跟使用XCTest一样,方法命令必须使用test开始,这里我们创建了一个测试函数,命令为testAmb 2:使用scheduler的createObserver方法创建一个观察者,指定类型为String.观察者将记录每一次接受事件的时间戳,除了不打印任何内容,其它像RxSwift中的操作符debug 3:创建一个可测试的观察者序列observableA 4: 使用next(_:_:)方法在指定的时间添加.next事件到observableA,第一个参数为添加时间,第二个参数为具体值。即在具体的时间发送该事件。对于需要发送值的就指定值,如果是向按钮点击是不需要发送值的,那么就为空,使用小圆括号()即可 5:创建另外一个可测试的观察者序列observableB,同样在指定时间添加.next事件到observableB 6:接下来使用amb操作符,ambObservable的类型时Observable<String> 7:接下来告诉调度者(scheduler)安排具体时间的动作 8:为观察者序列添加观察者,并且是在时间为0的时候开始订阅。返回的订阅者进行引用,这样在tearDown中进行释放处理 9:为了开始测试操作来验证结果,我们需要使用start方法,这里开始了虚拟时间的调度者,观察者(observer)将接受.next事件,事件是最初通过amb操作符之后得到的ambObservable中的时间和元素 10:现在可以收集和分析结果数据,这里使用map操作符来转换观察者事件到对应事件到元素值 11:现在,我们可以使用断言来比较实际的数据和预期的结果数据,测试结果是正确的,因为observableB中的事件将被发送,所以与预期结果一致。
6:测试filter操作符
func testFilter() { //1 let observer = scheduler.createObserver(Int.self) //2 let observable = scheduler.createHotObservable([ next(100, 1), next(200, 2), next(300, 3), next(400, 2), next(500, 1) ]) //3 let filterObservable = observable.filter { $0 < 3 } //4 scheduler.scheduleAt(0) { self.subscription = filterObservable.subscribe(observer) } //5 scheduler.start() //6 let results = observer.events.map { $0.value.element! } //7 XCTAssertEqual(results, [1,2,2,1]) } 分析: 1:创建一个观察者,指定观察者序列事件的元素类型为Int 2:创建一个观察者序列,并且添加元素,使用next方法 3:过滤原观察者序列得到过滤之后的观察者序列 4:在0秒时,开始订阅观察者序列,并且使用全局变量subscription引用 5:开始执行调度者(scheduler) 6:收集结果 7:判断结果与预期是否相符合,运行正确