ios - 如何模拟 EKEventStore

标签 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 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.calendars

谢谢


我换了

let status = EKEventStore.authorizationStatus(for: .event)

let status = type(of: store).authorizationStatus(for: .event)

最佳答案

我想你可以在这里使用 DI。您可以使用参数 store: EKEventStore 为其创建构造函数,并将其传递到那里,而不是在 SimpleCalendar 中创建存储变量:

init(store: EKEventStore = EKEventStore()) {/*code*/}

这样,您就可以传递自己的模拟对象。

覆盖类方法有什么问题?我现在无法检查,但假设这是可能的。

无论如何,其他选项用于模拟,您可以使用您正在使用的所有方法创建协议(protocol) - EventStoreProtocol。我认为这些方法必须在 EKEventStore 中,因此您可以使用扩展轻松地采用它:

extension EKEventStore: EventStoreProtocol {}

然后不是将 EKEventStore 传递给构造函数,而是将 EventStoreProtocol 传递给构造函数。

您的模拟对象将不是子类,而只是确认该协议(protocol)的类,实现所有必需的方法

对于类方法,使用 type(of: store).authorizationStatus 而不是 EKEventStore.authorizationStatus

关于你的问题,我唯一能想到的是下一个:

extension EKEventStore {
   func eventAuthorizationStatus() -> EKAuthorizationStatus {
      return EKEventStore.authorizationStatus(for: .event)
   }
}

然后在子类中覆盖这个方法。因为 EKEventStoreNSObject,所以它应该可以工作(但我不确定)。通过这种方式,您可以调用此方法而不是使用 type(of: store).authorizationStatus

但问题是 - 你真的需要这个吗?你就不能保持原样吗?如果不是,请检查此方法并告诉我它是否有效

关于ios - 如何模拟 EKEventStore,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45657594/

相关文章:

rest - 在 Intellij IDEA 中运行时,Grails 2.5.1 Restful Controller spock 单元测试失败并显示 406

objective-c - objective-c :非空实例方法中的内存泄漏

ios - setTexture 将我的 Sprite 的大小更改为更小,错误?

ios - 键盘动画移动 UITableView 部分标题

iphone - 使用默认选项卡 Controller 创建的项目...第一个 View Controller 不响应 addsubview

swift - 无法将返回表达式类型转换为带有闭包的返回类型?

swift 。 unowned 只能应用于类和类绑定(bind)协议(protocol)类型。弱工作正常

ios - 在 XCode 中随机化颜色

python - pip install -U 模拟 : Error

unit-testing - 我应该如何测试遗传算法