I am trying to mock CMMotionManager
for unit testing. Here is my abbreviated code:
protocol XMotionManager {
var isDeviceMotionAvailable: Bool { get }
var deviceMotionUpdateInterval: TimeInterval { get set }
}
extension CMMotionManager: XMotionManager {}
final class MockCMMotionManager: CMMotionManager {
private (set) var mockedIsDeviceMotionAvailable = true
override var isDeviceMotionAvailable: Bool {
mockedIsDeviceMotionAvailable
}
private var mockedDeviceMotionUpdateInterval: TimeInterval = 1.0
override var deviceMotionUpdateInterval: TimeInterval {
mockedDeviceMotionUpdateInterval
}
}
The protocol content is taken from the API. MockCMMotionManager
is supposed to override the two properties so that they can be set as required.
While this works for isDeviceMotionAvailable
, I get the following compiler error for deviceMotionUpdateInterval
:
Cannot override mutable property with read-only property 'deviceMotionUpdateInterval'
I don't understand this error because deviceMotionUpdateInterval
is not a read-only property, but declared as a var
.
Is something wrong with my code?
deviceMotionUpdateInterval
is a read-only property as it's a computed property without a setter.
Computed properties that don't have an explicit setter declared only have an implicit getter.
Your declaration of
override var deviceMotionUpdateInterval: TimeInterval {
mockedDeviceMotionUpdateInterval
}
is equivalent to this:
override var deviceMotionUpdateInterval: TimeInterval {
get {
mockedDeviceMotionUpdateInterval
}
}
To fix the issue, simply declare both a getter and setter explicitly for the computed property.
override var deviceMotionUpdateInterval: TimeInterval {
get {
mockedDeviceMotionUpdateInterval
}
set {
mockedDeviceMotionUpdateInterval = newValue
}
}