Ios 如何模拟EKEventStore
我有一个简单的函数,用于请求访问以在日历中添加事件Ios 如何模拟EKEventStore,ios,swift,unit-testing,mocking,Ios,Swift,Unit Testing,Mocking,我有一个简单的函数,用于请求访问以在日历中添加事件 typealias BoolCallback = (Bool) -> () class SimpleCalendar { let store: EKEventStore init(store: EKEventStore = EKEventStore()) { self.store = store } /// Request access to EventKit API for Cal
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)
}
}
}
}
}
有没有办法模拟EKEventStore来获取状态
我还有一个简单的功能,可以检查日历是否存在
func doesCalendarExist(name: String) -> Bool {
let calendars = store.calendars(for: .event)
if calendars.contains(where: { $0.title == name }) {
return true
}
return false
}
是否有方法模拟store对象以获取store.calendars
谢谢
我换了
let status = EKEventStore.authorizationStatus(for: .event)
到
我想你可以在这里用DI。您可以使用参数store:EKEventStore为其创建构造函数,并将其传递到那里,而不是将创建存储变量的责任放在SimpleCalendar中:
init(store: EKEventStore = EKEventStore()) {/*code*/}
这样,您就可以传递自己的模拟对象
重写类方法有什么问题?我现在不能查,但假设可能的话
不管怎样,另一个选项是模拟,您可以使用所有正在使用的方法创建协议-EventStoreProtocol。我认为这些方法必须在EKEventStore中,这样您就可以使用扩展轻松地采用它:
extension EKEventStore: EventStoreProtocol {}
然后,不要将EKEventStore传递给构造函数,而是传递给那里EventStoreProtocol
您的模拟对象将不是子类,而只是确认该协议的类,实现所有必需的方法
对于类方法,不要使用EKEventStore.authorizationStatus使用类型(of:store)。authorizationStatus
关于你的问题,我能想到的唯一一件事是:
extension EKEventStore {
func eventAuthorizationStatus() -> EKAuthorizationStatus {
return EKEventStore.authorizationStatus(for: .event)
}
}
然后在子类中重写此方法。因为EKEventStore是NSObject,所以它应该可以工作(但我不确定)。通过这种方式而不是使用类型(of:store).authorizationStatus您可以调用此方法
但问题是,你真的需要这个吗?你就不能保持原样吗?如果没有,请检查此方法并告诉我,如果它有效谢谢,这适用于'doesCalendarExist'函数,但您知道如何模拟类方法'EKEventStore.authorizationStatus'谢谢,我将再次解释类方法的问题。如您所见,我在代码中调用“EKEventStore.authorizationStatus”,这是一个类方法,因此我无法使用DI@ilan,我认为您可以-由于您的实例将是另一个类,您必须从该实例访问该类并调用其方法。因此,代替EKEventStore.authorizationStatus put type(of:store)。authorizationStatus我不理解代码部分,您可以将其添加到您的答案中吗?可能您可以编写更详细的说明:)请检查新的更新
extension EKEventStore {
func eventAuthorizationStatus() -> EKAuthorizationStatus {
return EKEventStore.authorizationStatus(for: .event)
}
}