Issue #218
- RxBlocking does not work with Variable and PublishSubject, see https://github.com/ReactiveX/RxSwift/blob/0b66f666ba6955a51cba1ad530311b030fa4db9c/Tests/RxSwiftTests/Observable%2BSubscriptionTest.swift#L165
Use homemade Recorder
class Recorder<T> {
    var items = [T]()
    let bag = DisposeBag()
    func on(arraySubject: PublishSubject<[T]>) {
        arraySubject.subscribe(onNext: { value in
            self.items = value
        }).disposed(by: bag)
    }
    func on(valueSubject: PublishSubject<T>) {
        valueSubject.subscribe(onNext: { value in
            self.items.append(value)
        }).disposed(by: bag)
    }
}
Then test
final class BookViewModelTests: XCTestCase {
    func testBooks() throws {
        let expectation = self.expectation(description: #function)
        let recorder = Recorder<Book>()
        let viewModel = BookViewModel(bookClient: MockBookClient())
        recorder.on(arraySubject: viewModel.books)
        viewModel.load()
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5, execute: {
            expectation.fulfill()
        })
        wait(for: [expectation], timeout: 2)
        XCTAssertEqual(recorder.items.count, 3)
    }
}
Need to use great timeout value as DispatchQueue is not guaranteed to be precise, a block needs to wait for the queue to be empty before it can be executed
Make expectation less cumbersome
extension XCTestCase {
    func waitOrFail(timeout: TimeInterval) {
        let expectation = self.expectation(description: #function)
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + timeout, execute: {
            expectation.fulfill()
        })
        wait(for: [expectation], timeout: timeout + 2)
    }
}
Start the conversation