Swift Combine PassThroughSubject not firing sink closure in XCTestCase

Viewed 1065

I was writing a unit test for some code I was working on in an iOS App and ran into very strange behavior.
The PassthroughSubject sink closure in my code wasn't running and thus the test was failing. When i uncomment the print line in the below code it passes. It also passes with no problems in a playground. I tried the whole quite Xcode delete derived data trick and that didn't work. I tried to move the class and unit test to a completely different project and it was still failing. To me this looks like an Apple bug but wanted to ask here to see if anyone has any insights. see the below code. Note i've simplified the code from my original project a bit to make is easier to read. This makes me feel like RxSwift is more polished than Combine at this point. Never saw anything like this happen with RxSwift.

class BadPassThroughSendClass {

    let publisher = PassthroughSubject<Any, Never>()
    var anyCancellable: AnyCancellable?
    var sinkClosureBlock: (()->())?

    init() {
        createSubscription()
    }

    func createSubscription() {
        let subscription = publisher
            .subscribe(on: DispatchQueue.global())
            .receive(on: DispatchQueue.global())
            .sink { [unowned self] event in
                sinkClosureBlock?()
            }
        anyCancellable = AnyCancellable(subscription)
    }

}

class UnitTests: XCTestCase {

    func testBadPassThroughClass() {
        let badClass = BadPassThroughSendClass()
        let sinkExpectation = expectation(description: "Sink closure should fire")
        badClass.sinkClosureBlock = {
            sinkExpectation.fulfill()
        }
        // print("pass the test with this line")
        badClass.publisher.send("my test message")
        waitForExpectations(timeout: 0.5)
    }

}
0 Answers
Related