如何使用RxSwift模拟tableView行选择

问题描述 投票:1回答:1

我有一个UITableViewController设置如下。

查看控制器

class FeedViewController: BaseTableViewController, ViewModelAttaching {

    var viewModel: Attachable<FeedViewModel>!
    var bindings: FeedViewModel.Bindings {
        let viewWillAppear = rx.sentMessage(#selector(UIViewController.viewWillAppear(_:)))
            .mapToVoid()
            .asDriverOnErrorJustComplete()

        let refresh = tableView.refreshControl!.rx
            .controlEvent(.valueChanged)
            .asDriver()

        return FeedViewModel.Bindings(
            fetchTrigger: Driver.merge(viewWillAppear, refresh),
            selection: tableView.rx.itemSelected.asDriver()
        )
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func bind(viewModel: FeedViewModel) -> FeedViewModel {
        viewModel.posts
            .drive(tableView.rx.items(cellIdentifier: FeedTableViewCell.reuseID, cellType: FeedTableViewCell.self)) { _, viewModel, cell in
                cell.bind(to: viewModel)
            }
            .disposed(by: disposeBag)

        viewModel.fetching
            .drive(tableView.refreshControl!.rx.isRefreshing)
            .disposed(by: disposeBag)

        viewModel.errors
            .delay(0.1)
            .map { $0.localizedDescription }
            .drive(errorAlert)
            .disposed(by: disposeBag)

        return viewModel
    }
}

查看模型

class FeedViewModel: ViewModelType {

    let fetching: Driver<Bool>
    let posts: Driver<[FeedDetailViewModel]>
    let selectedPost: Driver<Post>
    let errors: Driver<Error>

    required init(dependency: Dependency, bindings: Bindings) {

        let activityIndicator = ActivityIndicator()
        let errorTracker = ErrorTracker()

        posts = bindings.fetchTrigger
            .flatMapLatest {
                return dependency.feedService.getFeed()
                    .trackActivity(activityIndicator)
                    .trackError(errorTracker)
                    .asDriverOnErrorJustComplete()
                    .map { $0.map(FeedDetailViewModel.init) }
        }

        fetching = activityIndicator.asDriver()
        errors = errorTracker.asDriver()
        selectedPost = bindings.selection
            .withLatestFrom(self.posts) { (indexPath, posts: [FeedDetailViewModel]) -> Post in
                return posts[indexPath.row].post
        }
    }

    typealias Dependency = HasFeedService

    struct Bindings {
        let fetchTrigger: Driver<Void>
        let selection: Driver<IndexPath>
    }
}

我有绑定,检测何时选择行,其他方法由该绑定触发并呈现视图控制器。

我试图断言,当选择一行时,会显示一个视图,但是我无法成功模拟正在选择的行。

我尝试过的测试类似于

   func test_ViewController_PresentsDetailView_On_Selection() {

        let indexPath = IndexPath(row: 0, section: 0)
        sut.start().subscribe().disposed(by: rx_disposeBag)
        let viewControllers = sut.navigationController.viewControllers

        let vc = viewControllers.first as! FeedViewController
        vc.tableView(tableView, didSelectRowAt: indexPath)

        XCTAssertNotNil(sut.navigationController.presentedViewController)
    }

但这种情况失败了

无法识别的选择器发送到实例

如何在单元测试中选择模拟行?

ios swift uitableview xctest rx-swift
1个回答
2
投票

简短的回答是你没有。单元测试不是UIView对象和UI对象操作的地方。您想为此类测试添加UI测试目标。

© www.soinside.com 2019 - 2024. All rights reserved.