Макет объекта CLBeacon в Swift
Я искал в Интернете способ макетировать объект CLBeacon, чтобы протестировать один из моих классов. Все, что я могу найти, связано с COMockito, который совместим только с Objective-c.
Все, что мне нужно, это уметь создавать фиктивный CLBeacon и устанавливать его основные минорные значения и значения UUID. Проблема в том, что эти параметры доступны только для чтения.
Любая идея о том, что я мог бы сделать, чтобы иметь фиктивный CLBeacon с параметрами, которые я установил?
1 ответ
Я не уверен, почему я всегда забываю о NSCoding, но вы можете лечить объекты CLBeacon, используя синтаксис KVO. Я наконец получил модульное тестирование, работающее с CLBeacon, вот так:
let mockUUID = NSUUID(UUIDString: uuidString)
let testBeacon = CLBeacon()
testBeacon.setValue(testMajor, forKey: "major")
testBeacon.setValue(testMinor, forKey: "minor")
testBeacon.setValue(mockUUID, forKey: "proximityUUID")
testBeacon.setValue(CLProximity.Far.rawValue, forKey: "proximity")
Наверное, опоздал на вечеринку. Публикуйте его на случай, если кто-то столкнется с той же проблемой.
К сожалению, по крайней мере в iOS13 на момент написания все свойства CLBeacon экранированы внутри свойства _internal NSObject, которое, в свою очередь, содержит относительное значение.
В результате вы не можете использовать простой подход "значение / ключ". Также открытый общедоступный заголовок для класса CLBeacon не предоставляет относительный метод для инициализации с произвольным значением внутреннего объекта.
В этом суть создания класса FakeBeacon Obj-C, который повторно включает требуемый метод инициализации, разрешая такой вызов также из Swift, следующим образом:
var beacon = FakeBeacon(fakeWithUUID: UUID(uuidString: uuid)!,
major: 1,
minor: 100,
proximity: 2,
accuracy: 1,
rssi: 0,
timestamp: Date().timeIntervalSinceReferenceDate)
Очевидно, что не стоит включать такой код в производственный IPA, иначе отказ Apple неизбежен.