You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在RxSwift单元测试中模拟UITableView行选中操作

如何在RxSwift驱动的UITableViewController单元测试中模拟行选中操作?

你遇到的问题核心是直接调用传统UITableView代理方法并不适配RxSwift的事件绑定逻辑,才导致了unrecognized selector异常。我来帮你拆解问题并给出可行的解决方案:

问题根源

你在代码里用的是tableView.rx.itemSelected这个RxSwift封装的事件流处理行选中,而非传统的UITableViewDelegate方法。RxSwift会为UITableView设置内部代理对象监听事件,你的FeedViewController并没有被设置为tableView的delegate——直接调用tableView(_:didSelectRowAt:)不仅会触发找不到方法的错误,也根本不会触发Rx的事件流。

正确的模拟方式

要触发RxSwift绑定的行选中事件,你需要直接向tableView.rx.itemSelected这个Observable发送事件,而非调用代理方法。

修正后的测试代码

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
    
    // 确保视图已完成加载,Rx绑定逻辑已初始化完成
    vc.loadViewIfNeeded()
    
    // 直接向Rx的itemSelected事件流发送选中信号
    vc.tableView.rx.itemSelected.onNext(indexPath)
    
    XCTAssertNotNil(sut.navigationController.presentedViewController)
}

额外注意事项

还有个容易忽略的细节:你需要确保viewModel.posts已经有数据返回,否则selectedPost中的withLatestFrom操作符会因为没有数据源而无法触发后续的跳转逻辑。建议在测试时mock你的FeedService,返回测试用的Post数据:

// 定义Mock服务
class MockFeedService: HasFeedService {
    func getFeed() -> Single<[Post]> {
        // 返回一条测试数据,确保posts流有内容
        return Single.just([Post(id: "test_id", title: "Test Post")])
    }
}

// 在测试初始化时注入Mock服务
let mockDependency = FeedViewModel.Dependency(feedService: MockFeedService())
// 后续将这个mockDependency传入ViewModel初始化

这样就能保证选中行时,selectedPost能正确拿到对应的Post对象,进而触发视图控制器的跳转逻辑,你的断言也能正常验证。

内容的提问来源于stack exchange,提问作者Harry Blue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:31:35