如何对 iOS 应用程序委托方法的调用进行单元测试?
How Can I Unit Test Calling of iOS Application Delegate Methods?
我有一个与 GitHub API 集成的 iOS 应用程序。我正在对我的 OAuth
请求进行单元测试,这需要测试从 GitHub API 接收代码,我将使用该代码来交换令牌。
在我的AppDelegate.swift
中,我有以下方法,用于处理当用户授权我的应用程序使用他们的GitHub帐户时来自GitHub的回调:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return true
}
步骤如下:
- 打开应用程序。
- 使用URL授权GitHub帐户访问(https://github.com/login/oauth/authorize),呈现
SFSafariViewController
的实例,允许用户按'Authorize'按钮。
- GitHub 使用我在使用 GitHub 注册我的应用程序时提供的回调 URL 到我的应用程序,它会发送打开我的应用程序的通知。
- 执行上面的方法,我从
url
. 中检索 code
参数
但是,我一直在尝试寻找一种方法来测试它,而无需实际向 GitHub API 发出请求。我可以创建一个 URL
实例来模拟 GitHub 为我的应用程序提供的内容,但我想在不发出实际请求的情况下对其进行测试。
有没有办法对此进行单元测试,或者这是我不应该担心的事情,因为它由 OS 处理,而是只测试我的代码来解析 code
测试参数 URL
?
更新
在学习了 Jon 的 之后,我创建了一个测试 class 来模拟 GitHub 回调的运行:
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.")
}
}
然后,我创建了 AppDelegateMock.swift
来代替 AppDelegate.swift
,添加了在执行 GitHub 回调以打开我的应用程序时要调用的预期方法:
import UIKit
class AppDelegateMock: NSObject, UIApplicationDelegate {
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return true
}
}
测试通过,允许我测试处理从 GitHub int he url
参数返回的 code
参数的逻辑。
因为你想测试一个回调……只要让测试直接调用回调,就好像 GitHub 框架调用它一样。
围绕快乐路径编写简单的测试。然后,因为你正在处理你无法控制的外部数据,所以编写测试(如果 Swift 允许)用奇怪的 options
.
调用回调
我有一个与 GitHub API 集成的 iOS 应用程序。我正在对我的 OAuth
请求进行单元测试,这需要测试从 GitHub API 接收代码,我将使用该代码来交换令牌。
在我的AppDelegate.swift
中,我有以下方法,用于处理当用户授权我的应用程序使用他们的GitHub帐户时来自GitHub的回调:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return true
}
步骤如下:
- 打开应用程序。
- 使用URL授权GitHub帐户访问(https://github.com/login/oauth/authorize),呈现
SFSafariViewController
的实例,允许用户按'Authorize'按钮。 - GitHub 使用我在使用 GitHub 注册我的应用程序时提供的回调 URL 到我的应用程序,它会发送打开我的应用程序的通知。
- 执行上面的方法,我从
url
. 中检索
code
参数
但是,我一直在尝试寻找一种方法来测试它,而无需实际向 GitHub API 发出请求。我可以创建一个 URL
实例来模拟 GitHub 为我的应用程序提供的内容,但我想在不发出实际请求的情况下对其进行测试。
有没有办法对此进行单元测试,或者这是我不应该担心的事情,因为它由 OS 处理,而是只测试我的代码来解析 code
测试参数 URL
?
更新
在学习了 Jon 的
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.")
}
}
然后,我创建了 AppDelegateMock.swift
来代替 AppDelegate.swift
,添加了在执行 GitHub 回调以打开我的应用程序时要调用的预期方法:
import UIKit
class AppDelegateMock: NSObject, UIApplicationDelegate {
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return true
}
}
测试通过,允许我测试处理从 GitHub int he url
参数返回的 code
参数的逻辑。
因为你想测试一个回调……只要让测试直接调用回调,就好像 GitHub 框架调用它一样。
围绕快乐路径编写简单的测试。然后,因为你正在处理你无法控制的外部数据,所以编写测试(如果 Swift 允许)用奇怪的 options
.