简体   繁体   中英

How Can I Unit Test Calling of iOS Application Delegate Methods?

I have an iOS application that integrates with the GitHub API. I am unit testing my OAuth requests, which requires testing the receipt of a code from the GitHub API that I will use to exchange for a token.

In my AppDelegate.swift , I have the following method, which is used to handle the callback from GitHub when the user authorizes my application to use their GitHub account:

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    return true
}

The steps are as follows:

  1. Open the application.
  2. Using the URL for authorizing GitHub account access ( https://github.com/login/oauth/authorize ), an instance of SFSafariViewController is presented, allowing the user to press the 'Authorize' button.
  3. GitHub uses the callback URL to my application that I provided when registering my application with GitHub, which sends a notification to open my app.
  4. The method above is executed, where I retrieve the code parameter from url .

However, I am stuck trying to find a way to test this without actually making a request to the GitHub API. I can create a URL instance that mimics what GitHub supplies my application with, but I would like to test this without making an actual request.

Is there a way to unit test this, or is this something that I shouldn't worry about since it's handled by the OS, and instead, only test my code for parsing the code parameter of a test URL ?

UPDATE

After taking Jon's advice , I created a test class to allow me to simulate the GitHub callback in action:

class GitHubAuthorizationCallbackTests: XCTestCase {

    let delegate = AppDelegateMock()

    func test_AuthorizationCallbackFromGitHub_ApplicationOpensURL() {
        guard let url = URL(string: "xxxxxxxxxxxxxx://?code=********************") else { return XCTFail("Could not construct URL") }
        let isURLOpened = delegate.application(UIApplication.shared, open: url)
        XCTAssertTrue(isURLOpened, "URL is not opened from GitHub authorization callback. Expected URL to be opened from GitHub authorization callback.")
    }

}

Then, I created AppDelegateMock.swift to be used instead of AppDelegate.swift , adding in the intended method to be called when the GitHub callback is executed to open my app:

import UIKit

class AppDelegateMock: NSObject, UIApplicationDelegate {

    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
        return true
    }

}

The test passes, allowing me to test the logic that I need to test for handling the code parameter that is returned from GitHub int he url parameter of the method.

Because you want to test a callback… just have tests invoke the callback directly, as if the GitHub framework invoked it.

Write simple tests around the happy path. Then, because you're dealing with external data you can't control, write tests that (if Swift allows) invoke the callback with strange options .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM