理解 RXSwift:单元测试(四)
理解 RxSwift:為什么要使用 RxSwift(一)
理解 RxSwift:實(shí)現(xiàn)原理(二)
理解 RxSwift:單元測試(四)
這篇文章是閱讀 RxSwift: Reactive Programming with Swift 時(shí)記的筆記,介紹如何使用RxTest和RxBlocking對RxSwift編寫單元測試。
書上使用RxTest和RxBlocking對一個(gè) demo 進(jìn)行了完整的單元測試和講解,在這個(gè)過程中,我們可以熟悉一下RxSwift 單元測試的使用方法,了解單元測試的一般使用技巧和注意事項(xiàng)。
Demo 介紹
Demo 是一個(gè)轉(zhuǎn)換顏色的小應(yīng)用,根據(jù)用戶輸入的16進(jìn)制顏色代碼自動轉(zhuǎn)換為紅、綠、藍(lán)色值和顏色名字(若有)。
Demo 是使用MVVM模式實(shí)現(xiàn)的,邏輯代碼放在了ViewModel中,ViewController管理和控制View。ViewModel的主要代碼如下:
// Convert hex text to color color = hexString.asObservable().map { hex inguard hex.characters.count == 7 else { return .clear }let color = UIColor(hex: hex)return color}.asDriver(onErrorJustReturn: .clear)// Convert the color to an rgb tuple rgb = color.asObservable().map { color invar red: CGFloat = 0.0var green: CGFloat = 0.0var blue: CGFloat = 0.0color.getRed(&red, green: &green, blue: &blue, alpha: nil)let rgb = (Int(red * 255.0), Int(green * 255.0), Int(blue * 255.0))return rgb}.asDriver(onErrorJustReturn: (0, 0, 0))// Convert the hex text to a matching name colorName = hexString.asObservable().map { hexString inlet hex = String(hexString.characters.dropFirst())if let color = ColorName(rawValue: hex) {return "\(color)"} else {return "--"}}.asDriver(onErrorJustReturn: "")復(fù)制代碼接下來,主要針對ViewModel編寫單元測試。
編寫單元測試
首先介紹兩個(gè)RxSwift單元測試的庫,RxTest 和 RxBlocking,它們讓編寫測試用例更簡單。
RxTest 是一個(gè)獨(dú)立的庫,需要通過pod單獨(dú)安裝。RxTest提供了很多有用的功能,例如TestScheduler,它是一個(gè)虛擬時(shí)間scheduler,可以在指定時(shí)間發(fā)出事件,包括next、completed和error。
RxBlocking 也是獨(dú)立的庫,也需要通過pod安裝。它的作用是通過它的toBlocking(timeout:)方法將observable 轉(zhuǎn)換成 BlockingObservable。阻塞當(dāng)前線程,從而將異步操作轉(zhuǎn)換為同步操作,使測試變得容易。
打開TestingTests組中的TestingViewModel.swift,在類的頂部定義兩個(gè)屬性:
var scheduler: ConcurrentDispatchQueueScheduler! var disposeBag: Disposable! 復(fù)制代碼ConcurrentDispatchQueueScheduler 是并行隊(duì)列調(diào)度器,封裝了GCD的并行隊(duì)列。
setUp()方法,每個(gè)測試用例在開始前都會調(diào)用它。這里初始化一個(gè)新的 scheduler 和 viewModel。tearDown(),在每個(gè)測試完成時(shí)調(diào)用,一般執(zhí)行一些銷毀操作。
func testColorIsRedWhenHexStringIsFF0000_async() {let disposeBag = DisposeBag()// 1let expect = expectation(description: #function)// 2let expectedColor = UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha:1.0)// 3var result: UIColor! } 復(fù)制代碼驗(yàn)證異步操作是否按預(yù)期運(yùn)行,我們在測試中創(chuàng)建期望 expectation,然后在異步操作成功后調(diào)用fulfill()方法,表示滿足期望 expectation。
現(xiàn)在使用RxBlocking來實(shí)現(xiàn)同樣的事情:
func testColorIsRedWhenHexStringIsFF0000() {// 1let colorObservable =viewModel.color.asObservable().subscribeOn(scheduler)// 2viewModel.hexString.value = "#ff0000"// 3do {guard let result = try colorObservable.toBlocking(timeout:1.0).first() else { return }XCTAssertEqual(result, .red)} catch {print(error)} } 復(fù)制代碼轉(zhuǎn)載于:https://juejin.im/post/5d5a349e6fb9a06b0b1c752c
總結(jié)
以上是生活随笔為你收集整理的理解 RXSwift:单元测试(四)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2019牛客暑期多校训练营(第九场) E
- 下一篇: Shell-04