bogen
bogen

Reputation: 10432

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

Upvotes: 3

Views: 189

Answers (2)

Marco Cancellieri
Marco Cancellieri

Reputation: 66

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.

Upvotes: 2

Marco Cancellieri
Marco Cancellieri

Reputation: 66

You could set up the ViewModel to have an Observer, Action or MutableProperty (anything takes inputs) with Double type. Then bind the UISlider values to that in your ViewController.

So in your ViewController you could have a line like this: viewModel.sliderValue <~ slider.reactive.mapControlEvents(.valueChanged){ $0.value } where sliderValue could be of type MutableProperty<Double>.

In your tests you could then set the values like this: viewModelToTest.sliderValue.value = 10

Upvotes: 3

Related Questions