How to check a function / calculated property that requires information about a specific device?

I am developing a calendar application where I struggle to create tests for functions that use calendars on a user's device. The calendar: EKCalendar is taken from the user event repository, so when unit tests are run on the Xcode emulator, they fail because the calendar does not exist. Using my personal device works, but then the tests will not work on our build server.

What are good approaches to testing a function / computed property that uses the user calendar / eventstore?

  ///Return the user 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]() } 

Ignore that it returns an array, I'm not sure why it does it: p

+7
ios unit-testing swift xctest eventkit
source share
1 answer

So make it clear what you need to check in your function.

  • MeetingsFetcher().getUserEnterpriseCalendar()

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

My guess is the desire to test both of them. But since the problem you are mentioning, it seems to me impossible to check if your getUserEnterpriseCalendar function really works on the simulator, because it will not return anything anywhere (except that you create a script on your build server to allow the simulator to subscribe or add your calendar on it)

However, I can suggest that you make fun of the getUserEnterpriseCalendar function and make the assumption in your unit test that getUserEnterpriseCalendar will return the correct value in any environment. You may need to execute the function of the calculated value and pass the MeetingFetcher parameter for this.

 // 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!!!") } 

I hope this can help even just give you some ideas.

+2
source share

All Articles