我正在为我继承的遗留代码库中的类调试一些编写不当的单元测试。我看到开发人员没有正确测试计算属性。我想了解如何强制我的 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/