2

我正在尝试向现有代码库添加测试。

该应用程序使用带有协调器模式的 RxSwift。

AppCoordinator看起来像-

import UIKit
import RxSwift

enum AuthenticationState {
    case unknown, signedIn, signedOut
}

final class AppCoordinator: BaseCoordinator<Void> {
    private let window: UIWindow

    init(window: UIWindow) {
        self.window = window
    }

    override func start() -> Observable<Void> {
        coordinateToRoot(basedOn: .unknown)
        return .never()
    }

    /// Recursive method that will restart a child coordinator after completion.
    /// Based on:
    /// https://github.com/uptechteam/Coordinator-MVVM-Rx-Example/issues/3
    private func coordinateToRoot(basedOn state: AuthenticationState) {

        switch state {

        case .unknown:
            return showStartScene()
                .subscribe(onNext: { [weak self] authState in
                    self?.window.rootViewController = nil
                    self?.coordinateToRoot(basedOn: authState)
                })
                .disposed(by: disposeBag)

        case .signedOut:
            return showAuthenticationFlow()
                .subscribe(onNext: { [weak self] authState in
                    self?.window.rootViewController = nil
                    self?.coordinateToRoot(basedOn: authState)
                })
                .disposed(by: disposeBag)

        case .signedIn:
            return startHomeFlow()
                .subscribe(onNext: { [weak self] authState in
                    self?.window.rootViewController = nil
                    self?.coordinateToRoot(basedOn: authState)
                })
                .disposed(by: disposeBag)
        }

    }

    private func showStartScene() -> Observable<AuthenticationState> {
        let coordinator = StartCoordinator(window: window)
        return coordinate(to: coordinator).map { _ in return dependencies.authSvc.authState }
    }

    private func showAuthenticationFlow() -> Observable<AuthenticationState> {
        let coordinator = AuthCoordinator(window: window)
        return coordinate(to: coordinator).map { _ in return dependencies.authSvc.authState }
    }

    private func startHomeFlow() -> Observable<AuthenticationState> {
        let coordinator = HomeCoordinator(window: window)
        return coordinate(to: coordinator).map { _ in return dependencies.authSvc.authState }
    }
}

流程如下 - start调用showStartScene方法。这将检查令牌是否存在以及用户是否应该看到入职屏幕。一旦一切完成,它就会发出一个导致coordinateToRoot被调用的事件,使用最新的身份验证状态将用户引导到正确的Coordinator

我已经能够添加一个初始测试来断言window.rootViewController在开始时设置,但是我想断言周围的行为coordinateToRoot

class AppCoordinatorTests: XCTestCase {
    var sut: AppCoordinator!
    var window: UIWindow!
    var disposeBag: DisposeBag!

    override func setUp() {
        super.setUp()
        window = UIWindow(frame: .zero)
        sut = AppCoordinator(window: window)
        disposeBag = DisposeBag()
    }

    override func tearDown() {
        super.tearDown()
        window = nil
        sut = nil
        disposeBag = nil
    }

    func test_on_start_root_view_is_not_nil() {
        sut.start()
        .subscribe()
        .disposed(by: disposeBag)

        XCTAssertNotNil(window.rootViewController)
    }
}

每个协调器发出Void然后使用当前身份验证服务上的映射来调用递归方法并调用下一个有效的协调器。

我在想也许我在当前协调器上发出了一个事件,预设了结果,dependencies.authSvc.authState然后我可以断言UIViewController集合的类型为window.rootViewController

例如 -

XCTAssertTrue((window.rootViewController as Any) is SomeTypeOfViewController)

我想知道的是什么会使这个类更易于测试,而不是简单地制作所有东西public

我考虑过使用依赖注入来设置子协调器,然后使用存根来模拟事件,我不确定这是否是在类似的情况下的最佳选择RxSwift

4

0 回答 0