Как я могу проверить метод, вызванный в обработчике завершения UIAlertController? - PullRequest
0 голосов
/ 07 июля 2019

У меня есть протокол, который я прикрепляю к UIViewController, который я хотел бы разрешить представление UIAlertController.

import UIKit

struct AlertableAction {
    var title: String
    var style: UIAlertAction.Style
    var result: Bool
}

protocol Alertable {
    func presentAlert(title: String?, message: String?, actions: [AlertableAction], completion: ((Bool) -> Void)?)
}

extension Alertable where Self: UIViewController {
    func presentAlert(title: String?, message: String?, actions: [AlertableAction], completion: ((Bool) -> Void)?) {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
        actions.forEach { action in
            alertController.addAction(UIAlertAction(title: action.title, style: action.style, handler: { _ in completion?(action.result) }))
        }
        present(alertController, animated: true, completion: nil)
    }
}

Затем я просто вызываю этот метод в моем UIViewController в любое время, когда я хочу подать предупреждение

   self?.presentAlert(
        title: nil, message: "Are you sure you want to logout?",
        actions: [
            AlertableAction(title: "No", style: .cancel, result: false),
            AlertableAction(title: "Yes", style: .destructive, result: true)],
        completion: { result in
            guard result else { return }
            self?.viewModel.revokeSession()
        }
    )

Я пытаюсь в XCTestCase утверждать, что нажатие Да вызывает правильный метод для моей модели представления.

Я понимаю, что UITest позволит мне проверить видимое предупреждение и, возможно, затем нажать Да Я перенаправлен на маршрут выхода из системы, однако мне действительно интересно проверить сам метод.

Однако я не уверен, как проверить это в коде.

Ответы [ 2 ]

0 голосов
/ 08 июля 2019

Используя ViewControllerPresentationSpy , ваш тест может сказать

let alertVerifier = AlertVerifier()

, чтобы создать верификатор.Затем вызовите вашу функцию presentAlert.Затем вызовите

alertVerifier.executeAction(forButton: "Yes")

, чтобы выполнить данное действие.Наконец, вызовите захваченное закрытие:

alertVerifier.capturedCompletion?()

и проверьте ожидаемый результат.

0 голосов
/ 07 июля 2019

Я пытаюсь установить в XCTestCase, что нажатие кнопки Yes вызывает правильный метод для моей модели представления ... Я действительно заинтересован в тестировании самого метода.

Фактически он остаетсяНепонятно, что именно вы хотите проверить.Выяснение этого (что на самом деле нуждается в тестировании?) - большая часть битвы.Вы знаете, что result равно true, если заголовок Да, поэтому нет необходимости проверять что-либо на предмет фактического нажатия на это конкретное предупреждение.Возможно, то, что вы просите проверить, это просто:

    { result in
        guard result else { return }
        self?.viewModel.revokeSession()
    }

Другими словами, вы хотите знать, что происходит, когда result равно true, а не то, что происходит, когда оно false.Если это так, просто замените анонимную функцию реальной функцией (методом):

func revokeIfTrue(_ result:Bool) {
    guard result else { return }
    self?.viewModel.revokeSession()
}

и перепишите свой presentAlert, чтобы принять этот метод в качестве его завершения:

self?.presentAlert(
    title: nil, message: "Are you sure you want to logout?",
    actions: [
        AlertableAction(title: "No", style: .cancel, result: false),
        AlertableAction(title: "Yes", style: .destructive, result: true)],
    completion: revokeIfTrue
)

Теперь вы разбили функцию на что-то, что можно проверить независимо.

...