DEV Community

Khoa Pham
Khoa Pham

Posted on • Edited on

3 2

How to test PublishSubject in RxSwift

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)
    }
}

❤️ Support my apps ❤️

❤️❤️😇😍🤘❤️❤️

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

Top comments (0)

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay