Wednesday, March 22, 2023
HomeiOS Developmentios - The right way to anticipate the primary sink to get...

ios – The right way to anticipate the primary sink to get known as earlier than working a snapshot take a look at


I am working into a difficulty with snapshot testing a view that listens for updates from a view mannequin utilizing a Mix writer. The difficulty appears to be with the sink that’s acquired on the primary queue – the closure is what updates the view state. After I connect the view mannequin to the view, the closure contained in the sink is just not executed till after the snapshot take a look at runs, and I am left with an empty button! Is there a method to drive the sink’s closure to execute earlier than working the take a look at?

import Mix
import SnapshotTesting
import UIKit
import XCTest

struct ButtonState {
    let textual content: String
    let colour: UIColor
}

protocol ButtonViewModel {
    var state: AnyPublisher<ButtonState, By no means> { get }
}

ultimate class MyButton: UIButton {
    non-public var cancellable: Cancellable?

    func connect(viewModel: some ButtonViewModel) {
        cancellable = viewModel.state
            .obtain(on: DispatchQueue.most important)
            .sink { [weak self] in
                self?.convertState($0)
            }
    }

    non-public func convertState(_ state: ButtonState) {
        setTitle(state.textual content, for: .regular)
        setTitleColor(state.colour, for: .regular)
    }
}

struct MockViewModel: ButtonViewModel {
    var state: AnyPublisher<ButtonState, By no means> {
        currentState.eraseToAnyPublisher()
    }

    non-public let currentState: CurrentValueSubject<ButtonState, By no means>

    init(initialState: ButtonState) {
        currentState = CurrentValueSubject(initialState)
    }
}

ultimate class ButtonSnapshotTest: XCTestCase {
    func testMyButton() {
        let myButton = MyButton()
        myButton.connect(viewModel: MockViewModel(initialState: .init(textual content: "Hi", colour: .blue)))
        assertSnapshot(matching: myButton, as: .picture)
    }
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

five + thirteen =

Most Popular

Recent Comments