Модульное тестирование WKNavigationDelegate functions swift

У меня есть 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)
}

Я бы хотел, чтобы мой модульный тест убедился decisionHandler называется с правом WKNavigationActionPolicy на основе request.url из WKNavigationAction.

Однако я не могу понять, как проверить эту функцию. Вызов .load()в веб-просмотре не запускает функции делегата, когда я запускаю свой тестовый проект. Я также пытался вызвать эту функцию напрямую, чтобы проверить ее, но, похоже, невозможно создать новый экземпляр WKNavigationAction моего собственного (.request доступен только для чтения).

Как правильно использовать логику модульного тестирования в WKNavigationDelegate функции?

1 ответ

Решение

Ваш второй подход прямого вызова метода делегата - лучший подход, поскольку вы не полагаетесь на какое-либо поведение WebKit в своих модульных тестах.

Проблема невозможности создания экземпляра WKNavigationAction может быть решена путем создания подклассов. Создать MockNavigationAction который возвращает желаемый запрос, необходимый для тестирования, например:

final class MockNavigationAction: WKNavigationAction {
    var mockedRequest: URLRequest!
    override var request: URLRequest {
        return mockedRequest
    }

А затем в модульном тесте вызовите метод делегата напрямую:

func test_AllowsCorrectURL() {
    let sut = ViewController()
    let action = MockNavigationAction()
    action.mockedRequest = URLRequest(url: URL(string: "https://my-approved-url")!)
    let allowExpectation = expectation(description: "Allows action")
    sut.webView(WKWebView(), decidePolicyFor: action) { policy in
        XCTAssertEqual(policy, .allow)
        allowExpectation.fulfill()
    }
    waitForExpectations(timeout: 1.0)
}
Другие вопросы по тегам