[英]How to mock EKEventStore
I have a simple function for requesting access for adding events in the Calendar. 我有一个简单的函数来请求访问以在日历中添加事件。
typealias BoolCallback = (Bool) -> ()
class SimpleCalendar {
let store: EKEventStore
init(store: EKEventStore = EKEventStore()) {
self.store = store
}
/// Request access to EventKit API for Calendar intergration
///
/// - Parameter callback: returns if access was recived or denied
func requestAccess(callback: @escaping BoolCallback) {
let status = EKEventStore.authorizationStatus(for: .event)
switch status {
case .authorized:
callback(true)
// case .notDetermined: //should ask for access
// case .denied, .restricted: //should open a ask permission view
default:
store.requestAccess(to: .event) { accessGranted, _ in
DispatchQueue.main.async {
callback(accessGranted)
}
}
}
}
}
Is there a way to mock EKEventStore
for getting the status? 有没有办法模拟
EKEventStore
获取状态?
I also have a simple function that checks if a calendar exists. 我还有一个简单的函数来检查日历是否存在。
func doesCalendarExist(name: String) -> Bool {
let calendars = store.calendars(for: .event)
if calendars.contains(where: { $0.title == name }) {
return true
}
return false
}
Is there a way to mock the store objects for getting store.calendars
有没有办法模拟商店对象获取
store.calendars
Thanks 谢谢
I switched 我换了
let status = EKEventStore.authorizationStatus(for: .event)
to 至
let status = type(of: store).authorizationStatus(for: .event)
I think you can use DI here. 我想你可以在这里使用DI。 Instead of put responsibility of creating store var inside of SimpleCalendar you can create constructor for it with parameter store: EKEventStore and pass it there:
您可以使用参数存储:EKEventStore为其创建构造函数,而不是在SimpleCalendar中创建存储var的责任,并将其传递给:
init(store: EKEventStore = EKEventStore()) {/*code*/}
This way, you can pass your own mock object. 这样,您就可以传递自己的模拟对象。
What is the issue with overriding class method? 覆盖类方法有什么问题? I can't check it right now, but suppose it's possible.
我现在无法检查它,但假设它是可能的。
Any way, other option is for mocking you can create protocol with all the methods you're using - EventStoreProtocol . 无论如何,其他选项是用于模拟,您可以使用您正在使用的所有方法创建协议 - EventStoreProtocol 。 These methods must be in EKEventStore I think, so you can easily adopt it using extension:
我认为这些方法必须在EKEventStore中 ,因此您可以使用扩展名轻松采用它:
extension EKEventStore: EventStoreProtocol {}
Then instead of passing EKEventStore to constructor, pass there EventStoreProtocol . 然后,不是将EKEventStore传递给构造函数,而是传递EventStoreProtocol 。
Your mock object will be not subclass, but just class confirming to that protocol, implementing all required methods 您的模拟对象将不是子类,而只是确认该协议的类,实现所有必需的方法
For class method, instead of EKEventStore.authorizationStatus use type(of: store).authorizationStatus 对于类方法,使用type(of:store) .authorizationStatus而不是EKEventStore.authorizationStatus
The only thing I can think of regarding your problem is the next: 关于你的问题,我唯一能想到的就是下一个:
extension EKEventStore {
func eventAuthorizationStatus() -> EKAuthorizationStatus {
return EKEventStore.authorizationStatus(for: .event)
}
}
Then override this method in subclass. 然后在子类中重写此方法。 Because EKEventStore is NSObject , it should work (but I'm not sure).
因为EKEventStore是NSObject ,它应该工作(但我不确定)。 This way instead of using type(of: store).authorizationStatus you can call this method.
这样,您可以调用此方法,而不是使用type(of:store).authorizationStatus 。
But the question - do you really need this? 但问题是 - 你真的需要这个吗? Can't you just left it as is?
你不能把它原样留下吗? If no, check this approach and tell me, if it works
如果不是,请检查此方法并告诉我它是否有效
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.