【问题标题】:Mock a Reactive<UISlider>?模拟 Reactive<UISlider>?
【发布时间】:2018-04-25 13:52:43
【问题描述】:

我有一个 ViewModel,它在其初始化程序中作为输入

init(sliderEvents: Reactive<UISlider>) {

在测试中我想做类似的事情

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

例如为虚拟机模拟滑块从值 5 拖动到 15

我不清楚 RAC 是如何建立 Base: UISlider 的,所以我很困惑如何使 UISlider 的子类使这种模拟成为可能

【问题讨论】:

    标签: reactive-cocoa reactive-swift


    【解决方案1】:

    您可以将 ViewModel 设置为具有 ObserverActionMutableProperty(任何内容都需要输入)和 Double 类型。然后将 UISlider 值绑定到您的 ViewController 中。

    所以在你的 ViewController 中你可以有这样一行:viewModel.sliderValue &lt;~ slider.reactive.mapControlEvents(.valueChanged){ $0.value } 其中sliderValue 可以是MutableProperty&lt;Double&gt; 类型。

    在您的测试中,您可以设置如下值:viewModelToTest.sliderValue.value = 10

    【讨论】:

    • 您在技术上是正确的,但是在我给定的代码库中更改这将是太多的工作。所以仍在寻找是否可以只做一个模拟子类。
    【解决方案2】:

    这是另一种可行的方法:

    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
        }
    }
    

    然后您的 ViewModel 应该使用 Reactive&lt;SliderProtocol&gt; 进行初始化,并且您可以将 MockSlider 实例传递给它。模拟就像设置mockSlider.mockValue.value = 10 一样简单。

    【讨论】:

    • 很难让它与需要滑块成为 UIControl 子类的其余方法一起使用,并且我的视图控制器中的普通 UISlider 不符合 SliderProtocol,因为它只是一个 UISlider
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-08
    • 1970-01-01
    • 1970-01-01
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多