Swift 单元测试WKNavigationDelegate函数

Swift 单元测试WKNavigationDelegate函数,swift,io,webkit,Swift,Io,Webkit,我有一个UIViewController,它实现了一些WKNavigationDelegate函数,我想对这些函数中的逻辑进行单元测试。下面是一个例子: func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) ->

我有一个UIViewController,它实现了一些WKNavigationDelegate函数,我想对这些函数中的逻辑进行单元测试。下面是一个例子:

func webView(_ webView: WKWebView,
             decidePolicyFor navigationAction: WKNavigationAction,
             decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    guard let url = navigationAction.request.url else {
        decisionHandler(.cancel)
        return
    }

    if url.absoluteString != "https://my-approved-url" {
        decisionHandler(.cancel)
        return
    }

    decisionHandler(.allow)
}
我希望我的单元测试能够确保基于WKNavigationAction的request.url使用正确的WKNavigationAction策略调用decisionHandler

然而,我不知道如何测试这个函数。在运行测试项目时,在webview上调用.load()不会触发委托函数。我还尝试直接调用此函数来测试它,但似乎无法实例化我自己的新WKNavigationAction(.request是只读的)


在WKNavigationDelegate函数中单元测试逻辑的正确方法是什么?

测试委托方法最简单的方法就是简单地调用它们

这里的诀窍是传递允许单元测试验证行为的参数,为此您可以使用

对于导航策略委托方法的特定情况,您可以通过子类化
WKNavigationAction
,使用假,并将该类的实例作为输入参数传递给委托方法:

final类FakeNavigationAction:WKNavigationAction{
让urlRequest:urlRequest
var receivedPolicy:WKNavigationActionPolicy?
重写变量请求:URLRequest{URLRequest}
init(urlRequest:urlRequest){
self.urlRequest=urlRequest
super.init()
}
便利初始化(url:url){
self.init(urlRequest:urlRequest(url:url))
}
func decisionHandler(policy:WKNavigationActionPolicy){self.receivedPolicy=policy}
}
稍后,在单元测试中:

//设置
让testURL=URL(字符串:https://my-approved-url")!
让testAction=FakeNavigationAction(url:testURL)
//表演
controller.webView(webView,DecisionPolicyFor:testAction,decisionHandler:testAction.decisionHandler)
//断言
XCTAssertEqual(testAction.receivedPolicy,b:.取消)

另一种方法是为
request
使用getter,因为
WKNavigationAction
是一个Objective-C类,但这更像是一个黑客解决方案。

您可以直接调用该方法并断言使用预期参数调用了完成处理程序。否,我提到的问题是,我无法设置新WkNavigationAction()的.request属性,因此无法以这种方式测试逻辑。