Swift 5编写WKWebView加载请求单元测试遇错误的解决方法
错误原因
你遇到的Cannot call value of non-function type 'WKWebView?'错误,核心是命名混淆+方法签名不匹配:
- 你的ViewController里大概率有一个名为
webView的属性(类型是WKWebView?),Swift会优先把viewController.webView解析成这个属性,而非WKNavigationDelegate的代理方法; - 同时你调用的
decidePolicyFor方法签名不完整,漏掉了必须的decisionHandler闭包参数。
具体解决步骤
1. 匹配正确的代理方法签名
WKNavigationDelegate的decidePolicyFor方法完整签名带decisionHandler闭包,单元测试里必须传这个参数:
// 创建测试用的Mock对象 let mockWebView = WKWebView() let mockNavigationAction = MockNavigationAction() // 你自定义的Mock类 // 定义变量接收决策结果 var resultPolicy: WKNavigationActionPolicy? // 正确调用代理方法 viewController.webView(mockWebView, decidePolicyFor: mockNavigationAction) { policy in resultPolicy = policy } // 验证决策结果是否符合预期 XCTAssertEqual(resultPolicy, .allow)
2. 解决命名冲突
如果ViewController里有webView: WKWebView?属性,导致和代理方法名混淆,有两种处理方式:
- 重命名属性:把ViewController里的
webView属性改成其他名称(比如mainWebView),从根源避免混淆; - 强制调用代理方法:通过类型转换明确指定调用WKNavigationDelegate的方法,绕过属性的优先级:
(viewController as WKNavigationDelegate).webView(mockWebView, decidePolicyFor: mockNavigationAction) { policy in resultPolicy = policy }
3. 确保MockNavigationAction的有效性
你的MockNavigationAction需要正确模拟WKNavigationAction的必要属性(比如request),否则测试逻辑会失效。示例Mock类写法:
class MockNavigationAction: WKNavigationAction { private let mockRequest: URLRequest init(request: URLRequest) { self.mockRequest = request super.init() } override var request: URLRequest { return mockRequest } }
内容的提问来源于stack exchange,提问作者smartsanja
相关产品推荐
相关产品推荐

