iOS Swift4 如何保护接口(interface)中定义的计算属性不被赋值?

标签 ios swift unit-testing mocking computed-properties

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

为什么使用计算属性实现协议(protocol)的类可以覆盖计算属性并使其可写?

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

最佳答案

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

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

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

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

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

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

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

关于iOS Swift4 如何保护接口(interface)中定义的计算属性不被赋值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52027819/

相关文章:

iPhone 不调用指定号码,我想知道为什么?

iphone - NSZombieEnabled 似乎修复了我的错误

ios - Swift 中的分段文件上传

swift - 嵌套 Bool 总是返回 Nil

swift - 0 和文本框文本之间的随机数

Python 多重继承单元测试 -

ios - 模拟器 10.2.1 命令 + R 在 react native 中不起作用

ios - Swift - UIImage 未显示在 TableViewCell 中(单击时显示,单击其他单元格时消失)

visual-studio-2008 - 为什么 Visual Studio 2008 不会在“测试结果”窗口中永久显示“类名称”列?

javascript - 强制 typescript 不删除未使用的引用