如何测试需要设备特定信息的 function/computed 属性?
How to test a function/computed property that needs device specific information?
我正在开发一个日历应用程序,我正在努力为使用用户设备上的日历的功能创建测试。这
calendar: EKCalendar
变量取自用户事件存储,因此当单元测试 运行 在 XCode 的模拟器上时,它们会失败,因为日历不存在。使用我的个人设备可以,但在我们的构建服务器上测试会失败。
测试使用用户 calendar/eventstore 的 function/computed 属性 的好方法是什么?
///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
所以让我们澄清一下您实际需要在函数中测试的内容。
MeetingsFetcher().getUserEnterpriseCalendar()
calendar.title.firstMatch(from: Regex.organizerNameFromEKCalendar)
我的假设是您想同时测试它们。但正如你提到的问题,我认为不可能真正测试你的 getUserEnterpriseCalendar
函数是否在模拟器上正常工作,因为它不会 return 任何地方 (除非你创建脚本在你的构建服务器上让模拟器订阅或添加你的日历)
不过,我可以建议您模拟 getUserEnterpriseCalendar
函数,并在您的单元测试中假设 getUserEnterpriseCalendar
将在任何环境中 return 正确值。您可能需要更改计算的 属性 才能运行并将 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!!!")
}
我希望它能对你有所帮助,即使只是给你一些想法。
我正在开发一个日历应用程序,我正在努力为使用用户设备上的日历的功能创建测试。这
calendar: EKCalendar
变量取自用户事件存储,因此当单元测试 运行 在 XCode 的模拟器上时,它们会失败,因为日历不存在。使用我的个人设备可以,但在我们的构建服务器上测试会失败。
测试使用用户 calendar/eventstore 的 function/computed 属性 的好方法是什么?
///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
所以让我们澄清一下您实际需要在函数中测试的内容。
MeetingsFetcher().getUserEnterpriseCalendar()
calendar.title.firstMatch(from: Regex.organizerNameFromEKCalendar)
我的假设是您想同时测试它们。但正如你提到的问题,我认为不可能真正测试你的 getUserEnterpriseCalendar
函数是否在模拟器上正常工作,因为它不会 return 任何地方 (除非你创建脚本在你的构建服务器上让模拟器订阅或添加你的日历)
不过,我可以建议您模拟 getUserEnterpriseCalendar
函数,并在您的单元测试中假设 getUserEnterpriseCalendar
将在任何环境中 return 正确值。您可能需要更改计算的 属性 才能运行并将 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!!!")
}
我希望它能对你有所帮助,即使只是给你一些想法。