如何测试需要设备特定信息的函数/计算属性?

时间:2018-02-13 12:55:41

标签: ios swift unit-testing xctest eventkit

我正在开发一个日历应用程序,我正在努力为使用用户设备上的日历的功能创建测试。该 calendar: EKCalendar变量来自users事件存储,因此当单元测试在XCode的模拟器上运行时,它们会因日历不存在而失败。使用我的个人设备可以正常工作,但测试会在我们的构建服务器上失败。

测试使用用户日历/事件存储的函数/计算属性有哪些好方法?

    ///Return the user's name. If this hasn't been saved extract their name from their Enterprise calendar and save it.
static var name: String? {
    if let savedName = defaults.string(forKey: "name") {
        return savedName
    }

    // calendar is a specific EKCalendar members of my company will have.
    guard let calendar = MeetingsFetcher().getUserEnterpriseCalendars().first,
        let parsedName = calendar.title.firstMatch(from: Regex.organizerNameFromEKCalendar) else {
            return nil
    }
    defaults.set(parsedName, forKey: "name")
    return parsedName
}


func getEnterpriseCalendars() -> [EKCalendar]{
    guard EKEventStore.authorizationStatus(for: .event) == .authorized else { return [EKCalendar]() }
    for calendar in MeetingsFetcher.eventStoreClass.calendars(for: .event) {
        if calendar.source.title.range(of: "IBM") != nil{
            return [calendar]
        }
    }
    return [EKCalendar]()
}

忽略它正在返回一个数组,我不确定为什么会这样做:p

1 个答案:

答案 0 :(得分:2)

因此,请澄清一下您在功能中必须测试的内容。

  1. MeetingsFetcher().getUserEnterpriseCalendar()

  2. calendar.title.firstMatch(from: Regex.organizerNameFromEKCalendar)

  3. 我的假设是你想要测试它们。但是你提到的问题我认为实际测试你的getUserEnterpriseCalendar函数是否在模拟器上正常工作是不可能的,因为它不会返回任何(除了你在构建服务器上创建脚本让模拟器订阅或添加您的日历)

    但是,我可以建议您模拟getUserEnterpriseCalendar函数,并在单元测试中假设getUserEnterpriseCalendar将在任何环境中返回正确的值。您可能需要输入计算属性以使其起作用,并将MeetingFetcher作为参数传递给它。

    // function modification
    static func name(from meetingFetcher: MeetingFetcher) -> String {
        if let savedName = defaults.string(forKey: "name") {
            return savedName
        }
    
        // calendar is a specific EKCalendar members of my company will have.
        guard let calendar = meetingFetcher.getUserEnterpriseCalendar().first,
            let parsedName = calendar.title.firstMatch(from: Regex.organizerNameFromEKCalendar) else {
                return nil
        }
        defaults.set(parsedName, forKey: "name")
        return parsedName
    }
    
    // In testing code.
    func testOrganizationCalendar() {
    
        class MockedMeetingFetcher: MeetingFetcher {
            override func getUserEnterpriseCalendars() -> [EKCalendar] {
                let calendar1 = EKCalendar()
                calendar1.title = "ExpectedToMatchRegexTitle"
                return [calendar1]
            }
        }
    
        XCTestAssertEqual(YourClass.name(from: MockedMeetingFetcher()), "Hure!!!")
    
    }
    

    我希望它甚至可以给你一些想法。