0

I have a WKWebView to loads a basic url request.

extension ViewController: WKUIDelegate, WKScriptMessageHandler, WKNavigationDelegate {
    func webView(
        _ webView: WKWebView,
        createWebViewWith configuration: WKWebViewConfiguration,
        for navigationAction: WKNavigationAction,
        windowFeatures: WKWindowFeatures
    ) -> WKWebView? {
        if navigationAction.targetFrame == nil, let url = navigationAction.request.url {
            if url.description.lowercased().range(of: "http://") != nil ||
                url.description.lowercased().range(of: "https://") != nil ||
                url.description.lowercased().range(of: "mailto:") != nil {
                UIApplication.shared.open(url)
            }
        }
        return nil
    }

    func openSite() {
        guard let myUrl = URL(string: "https://www.myurl.com") else { return }
        let request = URLRequest(url: myUrl)

        webView?.load(request)
        self.webView.sizeToFit()
    }

Now I want to write a unit test to verify webview correctly load the request. I have followed this approach https://stackoverflow.com/a/63827560/627667 and created a mock navigation action.

func test_AllowsCorrectURL() {
        let action = MockNavigationAction()
        action.mockedRequest = URLRequest(url: URL(string: "https://www.myurl")!)
        let allowExpectation = expectation(description: "Allows action")
        viewController.webView(WKWebView(), decidePolicyFor: action) { policy in
            XCTAssertEqual(policy, .allow)
            allowExpectation.fulfill()
        }
        waitForExpectations(timeout: 1.0)
    }

However on this line viewController.webView(WKWebView(), decidePolicyFor: action) I am getting below error.

Cannot call value of non-function type 'WKWebView?'

Swift version 5. How to get rid of this error? Your suggestions highly appreciated.

smartsanja
  • 4,413
  • 9
  • 58
  • 106
  • Can you also share your `viewController` code? There are more `WKNavigationDelegate` methods with `decidePolicyFor` parameter label. – dziobaczy Nov 25 '22 at 12:53
  • 1
    Yes, I have updated the ViewController code – smartsanja Nov 25 '22 at 13:02
  • In the meantime I wrote a comment and I think I got it right for You, please take a look c: – dziobaczy Nov 25 '22 at 13:04
  • @dziobaczy thanks a lot for the explanation. That means either I have implement same delegate method in the viewcontroller or else i need to use the same method which is in the viewcontroller in the unit test as well – smartsanja Nov 25 '22 at 13:08
  • Yes, when you want to call particular method on the vc it needs to exist on it the same way you can't access a property that doesn't exist. Normally you can call any method from protocol because they're all required to exist in swift itself you can't have optional methods this is objc way that's just still used by this delegate for swift you would probably add empty method implementations to the protocol extension. (Which tho preventing compile time issue or runtime crash could cause you not knowing why your code is not being run) – dziobaczy Nov 25 '22 at 13:18

1 Answers1

0

I'm almost sure that this is related to you adding implementation for another method of WKNavigationDelegate to your vc. It has few of them containing decidePolicyFor parameter label and if you will omit the implementation for the one that you are trying to call in here you won't be able to do so.

The reason of that (to my understanding) is that these are methods marked as optional on the protocol so your class doesn't need to implement them and if compiler won't find implementation of the method that you try to call it will complete with the error.

Since you shared a concrete example, you're basing your solution on check if your vc is having a method with exactly this signature:

extension ViewController: WKNavigationDelegate {

    func webView(
        _ webView: WKWebView,
        decidePolicyFor navigationAction: WKNavigationAction,
        decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
          // ...
        }
}
dziobaczy
  • 891
  • 9
  • 17