【问题标题】:iOS Swift4 how to protect computed property defined in interface from assignment?iOS Swift4如何保护接口中定义的计算属性不被赋值?
【发布时间】:2023-03-13 03:52:01
【问题描述】:

我正在为我继承的遗留代码库中的一个类调试一些编写不佳的单元测试。我看到开发人员没有正确测试计算属性。我想了解如何强制我的userEnabledFeature 在 Fake 类中只读。

为什么具有计算属性的类实现协议可以覆盖计算属性并使其可写?

public protocol FeatureManager {
    var userEnabledFeature : Bool { get }
}

public class FakeFeatureManagerForTesting: FeatureManager {
    public var userEnabledFeature = false //is this legal? Why is compiler not complaining?

    public func updateUserEnabledFeature(enabled: Bool){
        //this should not be possible - how do I prevent overwriting computed property?
        userEnabledFeature = enabled
    }
}

ActualFeatureManagerClass {
    public var userEnabledFeature: Bool {
        if featureManager.cachedFeatures.filter { $0.enabled == true}
        {
            //do more checks, return true or false
        }
        return false //default
    }
}

【问题讨论】:

  • FakeFeatureManagerForTesting中的属性改为:public var userEnabledFeature: Bool { return false }

标签: ios swift unit-testing mocking computed-properties


【解决方案1】:
public class FakeFeatureManagerForTesting: FeatureManager {
  public var userEnabledFeature = false //is this legal? Why is compiler not complaining?
}

协议是说符合它的成员必须有一个可以读取的Bool 属性userEnabledFeature,而不是只读属性。但是,如果您有一个以协议为类型的变量,则即使该变量的值是 implementation 也可以写,它也不允许您分配属性。

协议没有定义它是如何实现的(如果它的计算属性、存储属性等),但它的签名是什么以及它应该是只读的还是必须有 也可以写访问。如果将其标记为只读,则实现仍然可以使写可写,因为在这种情况下协议并不真正关心写访问。

你可以像这样实现计算属性:

public class FakeFeatureManagerForTesting: FeatureManager {
  public var userEnabledFeature: Bool { 
    // do some work here and return value or fallback to false
    return false
  }
}

另一方面,您也可以只有私有可设置属性,只能从文件或类/结构中更改:

public class FakeFeatureManagerForTesting: FeatureManager {
  public private(set) var userEnabledFeature = false

  public func updateUserEnabledFeature(enabled: Bool) {
    userEnabledFeature = enabled // will work just fine
  }
}

let manager = FakeFeatureManagerForTesting()
manager.updateUserEnabledFeature(enabled: true) // will work
manager.userEnabledFeature = true // won't compile, because modifying is allowed privately only

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-22
    • 2011-05-04
    • 2015-12-29
    • 2015-04-18
    • 2015-09-25
    • 2021-12-30
    • 1970-01-01
    相关资源
    最近更新 更多