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 ❤️

❤️❤️😇😍🤘❤️❤️

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Community—every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple “thank you” goes a long way—express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay