Дейнит позвонил, но тестирование на мятной не закончено - PullRequest
0 голосов
/ 29 апреля 2020

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

Мой класс координатора

public final class AppCoordinator: Coordinator {

        public var childCoordinators: [Coordinator] = []

        public var navigationController: UINavigationController
        var window: UIWindow?

        public init(window: UIWindow?) {
            self.window = window
            let secController =  SecController()
            self.navigationController = UINavigationController(rootViewController: secController)
            secController.delegate = self

        }
        public func start() {
            window?.rootViewController = navigationController
            window?.makeKeyAndVisible()
        }
    }

    extension AppCoordinator: SecControllerDelegate, SignInControllerDelegate {
        public func removeSingIn() {

            self.childCoordinators.removeFirst()
        }

        public func showSignIn() {
            let signInCoordinator = SignInCoordinator(navigationController: self.navigationController)
            signInCoordinator.delegate = self
            self.childCoordinators.append(signInCoordinator)
            signInCoordinator.start()

        }

}

Класс модульного теста

class AppCoordinatorTests: XCTestCase {
    var coordinator: AppCoordinator!

    override func setUp() {
        super.setUp()
        coordinator = AppCoordinator(window: UIWindow())
    }

    override func tearDown() {
        coordinator = nil
        super.tearDown()
    }

    func testStartMethod() {
        coordinator.start()
        XCTAssertNotNil(coordinator.window?.rootViewController)
    }

    func testShowSignIn() {
        coordinator.showSignIn()
        XCTAssertFalse(coordinator.childCoordinators.isEmpty)
        XCTAssertTrue(coordinator.navigationController.visibleViewController is SignInController)
        }
}

при попытке проверить testShowSignIn всегда не удается из-за deinit вызова removeSingIn функции

public class SignInController: UIViewController {

    public weak var delegate: SignInControllerDelegate?

    public init() {

        super.init(nibName: nil, bundle: nil)
    }

    deinit {
        self.delegate?.removeSingIn()
    }

}

1 Ответ

0 голосов
/ 29 апреля 2020

Давайте рассмотрим шаги:

  • testShowSignIn вызовы coordinator.showSignIn(), где coordinator - это AppCoordinator.
  • showSignIn() создает экземпляр SignInCoordinator, и устанавливает его делегатом экземпляр AppCoordinator.

Теперь мы достигли важной части:

  • Мы достигли конца showSignIn(). SignInCoordinator выходит из области видимости, поэтому Swift уничтожает его.

Ничто не поддерживает ссылку на SignInCoordinator. Но вы хотите проверить взаимодействие между AppCoordinator и SignInCoordinator. Код борется с вами, потому что AppCoordinator решает самостоятельно создавать и уничтожать SignInCoordinator.

Вы можете проверить его, изменив дизайн. У вас есть пара опций.

Опция 1: Измените AppCoordinator, чтобы иметь вычисленное свойство с отложенным вычислением, которое возвращает SignInCoordinator. Это может сработать, если вы согласны с этим дизайном. Тогда SignInCoordinator продолжит жить, так что тест может запросить его. Это улучшает тестируемость AppCoordinator, выставляя SignInCoordinator.

Вариант 2: Попросите тест создать SignInCoordinator и передать его в как аргумент showSignIn(). Тогда жизненный цикл SignInCoordinator будет полностью управляться за пределами AppCoordinator.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...