添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By Navdeep Singh

RxTest and RxBlocking are part of the RxSwift repository. They are made available via separate pods, however, and so require separate imports.

RxTest provides useful additions for testing Rx code. It includes TestScheduler , which is a virtual time scheduler, and provides methods for adding events at precise time intervals.

RxBlocking , on the other hand, enables you to convert a regular Observable sequence to a blocking observable, which blocks the thread it’s running on until the observable sequence completes or a specified timeout is reached. This makes testing asynchronous operations much easier.

Let’s look at each one now.

RxTest

As described above, RxTest is part of the same repository as RxSwift. There is one more thing to know about RxTest before we dive into some RxTesting: RxTest exposes two types of Observables for testing purposes.

  • HotObservables
  • ColdObservables
  • HotObservables replay events at specified times using a test scheduler, regardless of whether there are any subscribers.

    ColdObservables work more like regular Observables, replaying their elements to their new subscribers upon subscription.

    RxBlocking

    If you are familiar with expectations in XCTest , you will know that it’s another way to test asynchronous operations. Using RxBlocking just happens to be way easier. Let’s start with a small implementation so we can see how to take advantage of this library while testing asynchronous operations.

    Testing with RxBlocking

    We will start a new test and create an Observable of 10, 20, and 30, as follows:

    func testBlocking(){        let observableToTest = Observable.of(10, 20, 30)    }
    

    Now we will define the result as equal to calling toBlocking() on the observable we created:

    let result = observableToTest.toBlocking()
    

    toBlocking() returns a blocking Observable to a straight array, as you can see here:

    We will need to use the first method if we want to discover which is a throwing method. So we will wrap it in a do catch statement, and then we will add an AssertEquals statement if it is successful, as follows:

    func testBlocking(){        let observableToTest = Observable.of(10, 20, 30)        do{            let result = try observableToTest.toBlocking().first()            XCTAssertEqual(result, 10)        } catch {        }    }
    

    Alternatively, an Assert fails if it’s not this:

    do{            let result = try observableToTest.toBlocking().first()            XCTAssertEqual(result, 10)        } catch {            XCTFail(error.localizedDescription)        }
    

    That’s it! Let’s run the test, and you will see that the test passes. We can simplify this test with just two lines of code by forcing the try.

    Again, this is more acceptable on test than production code. We will comment out the do catch statement and then write the assert equals in a single line, as follows:

    XCTAssertEqual(try! observableToTest.toBlocking().first(), 10)
    

    Rerun the test, and you will see that the test passes once again. The overall code with comments looks like this:

    func testBlocking(){        let observableToTest = Observable.of(10, 20, 30)//        do{//            let result = try observableToTest.toBlocking().first()//            XCTAssertEqual(result, 10)//        } catch {//            XCTFail(error.localizedDescription)//        }        XCTAssertEqual(try! observableToTest.toBlocking().first(), 10)    }
    

    How’s that for succinct? Truth be told, that Observable sequence would actually be synchronous already if we printed emitted elements in a subscription to it followed by a marker. The marker will be printed after the subscription’s completed event.

    To test an actual asynchronous operation, we will write one more test. This time, we will use a concurrent scheduler on a background thread, as follows:

    func testAsynchronousToArry(){        let scheduler = ConcurrentDispatchQueueScheduler(qos: .background)    }
    

    Now, we will create an Observable of the simple sequence of integers. We will use map to double each value, as follows:

    let intObservbale = Observable.of(10, 20, 30)            .map{ $0 * 2 }
    

    Then, we will subscribe on the scheduler:

    let intObservbale = Observable.of(10, 20, 30)            .map{ $0 * 2 }            .subscribeOn(scheduler)
    

    Now we will write a do catch statement that is similar to the last test and calls toBlocking on the Observable, which should be observed on the main scheduler, as follows:

    do{   let result = try intObservbale.observeOn(MainScheduler.instance).toBlocking().toArray()   } catch {   }
    

    Then, we will add the same assertions as the previous example:

    do{   let result = try intObservbale.observeOn(MainScheduler.instance).toBlocking().toArray()            XCTAssertEqual(result, [20, 40, 60])        } catch {            XCTFail(error.localizedDescription)        }
    

    Now we will run the test, and you will note that it passes with the green check mark in the gutter.

    Note that the marker is printed before the emitted elements in the console, as shown:

    This is because these operations were executed asynchronously.

    For other updates you can follow me on Twitter on my twitter handle @NavRudraSambyal

    To work with examples of hot and cold observables, you can find the link to my book Reactive programming in Swift 4

    Thanks for reading, please share it if you found it useful :)

    freeCodeCamp is a donor-supported tax-exempt 501(c)(3) charity organization (United States Federal Tax Identification Number: 82-0779546)

    Our mission: to help people learn to code for free. We accomplish this by creating thousands of videos, articles, and interactive coding lessons - all freely available to the public.

    Donations to freeCodeCamp go toward our education initiatives, and help pay for servers, services, and staff.

    You can make a tax-deductible donation here . Learn CSS Transform Build a Static Blog Build an AI Chatbot What is Programming? Python Code Examples Open Source for Devs HTTP Networking in JS Write React Unit Tests Learn Algorithms in JS How to Write Clean Code Learn PHP Learn Java Learn Swift Learn Golang Learn Node.js Learn CSS Grid Learn Solidity Learn Express.js Learn JS Modules Learn Apache Kafka REST API Best Practices Front-End JS Development Learn to Build REST APIs Intermediate TS and React Command Line for Beginners Intro to Operating Systems Learn to Build GraphQL APIs OSS Security Best Practices Distributed Systems Patterns Software Architecture Patterns