Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RxBlocking does't work well with PublishSubject and a suggestion to improve it #2617

Open
xrloong opened this issue Aug 1, 2024 · 1 comment

Comments

@xrloong
Copy link

xrloong commented Aug 1, 2024

Short description of the issue:

I know there is already an issue, #1480, discussing this case, and @abdulowork had replied the reason and gave an alternative way to test PublishSubject.

But I don't think the limitation is reasonable since when we test some mechanism using Observable, we not know if this observable is derived from PublishSubject or not.

Moreover, it's possible that developers may change underlying implementation from ReplaySubject to PublishSubject for some reason, and then related test cases failed

Thus, I suggest to fix the behavior of for Observable.toBlocking(). Here is the possible implementation:

private var disposeBag: DisposeBag!
extension ObservableConvertibleType {
    public func toBlocking(timeout: TimeInterval? = nil) -> BlockingObservable<Element> {
         let replaySubject = ReplaySubject<Element>.createUnbounded()

         // forward all events to replaySubject
         asObservable().subscribe(replaySubject)
             .disposed(by: disposeBag)

         return BlockingObservable(timeout: timeout, source: replaySubject)
    }
}
@markst
Copy link

markst commented Aug 11, 2024

Might share this for inspiration: https://github.com/albertbori/TestableCombinePublishers

Where by it's possible to setup an expectation which collects the output of a publisher, then later the expectation can be waited until an output is produced. For example:

let expected = sut.currentPlayingInfo.playProgress
    .compactMap { $0?.progress }
    .map { $0.rounded() }
    .first()
    .expect(expectTime) // <- Using `TestableCombinePublishers`

await play(
    actionHandler: sut.actionHandler,
    media: media,
    seek: initialTime
)

await sut.actionHandler.performAction(.skipBackward(skipInterval))

expected.waitForExpectations(timeout: timeout)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants