Search code examples
reactive-cocoareactive-swift

Mock a Reactive<UISlider>?


I have a ViewModel which has as an input in its initializer

init(sliderEvents: Reactive<UISlider>) {

In the test i want to do something like

slider.send(.touchDownInside)
slider.send(.valueChanged, 5)
slider.send(.valueChanged, 15)

To simulate for the VM that the slider was dragged from value 5 to 15 for example

It is unclear to me how RAC has built up the Base: UISlider so i'm confused as to how to make the subclass of UISlider to make this kind of mocking possible


Solution

  • Here's another approach that should work:

    protocol SliderProtocol {
        var valuesSignal: Signal<Float, NoError> { get }
    }
    
    extension UISlider: SliderProtocol {
        var valuesSignal: Signal<Float, NoError> {
            return reactive.values
        }
    }
    
    extension Reactive where Base: SliderProtocol {
        var values: Signal<Float, NoError> {
            return base.valuesSignal
        }
    }
    
    class MockSlider: SliderProtocol {
        let mockValue = MutableProperty<Float>(0)
    
        var valuesSignal: Signal<Float, NoError> {
            return mockValue.signal
        }
    }
    

    Your ViewModel should then init with Reactive<SliderProtocol> and you could pass the MockSlider instance to it. Mocking would be as simple as setting mockSlider.mockValue.value = 10.