在RxSwift中测试UITableView.rx.itemSelected回调

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

我有一个绑定到实例var myStrings: BehaviorRelay<[String]>的tableView,因此tableView中每个单元格的标签都设置为myStrings中每个字符串的值:

myStrings.bind(to: tableView.rx.items(cellIdentifier: cellReuseId, cellType: MyTableCell.self)) { row, str, cell in
            cell.textLabel?.text = str
        }.disposed(by: disposeBag)

我已订阅tableView上的项目选择。

tableView.rx.itemSelected.subscribe(onNext: { indexPath in
            let currentStr: String = try! self.tableView.rx.model(at: indexPath)
            self.delegate?.use(currentStr)
        }).disposed(by: disposeBag)

我将如何测试在单元测试中订阅的itemSelected所拥有的封闭?

ios swift rx-swift reactivex rx-cocoa
1个回答
0
投票

[不确定使用RxSwift时为什么需要使用委派,但是测试所用内容的一种方法是将表视图注入到在代码段中使用表视图的对象中,并还创建一个模拟对象,该对象符合您的表格视图单元格的委托(您要测试的订阅中的委托)。前者将允许您在单元测试用例中创建表格视图,并以编程方式在其中选择一个单元格。然后,后者将允许您测试是否使用正确的字符串调用了订阅中调用的委托方法。

要测试您的委托,请在单元测试中使用符合委托协议的模拟对象,为您的方法设置一个“间谍”,然后对该对象及其间谍回调运行断言:

class MockDelegateObject: TableViewCellDelegate {
    var stubUse: (() -> String)?

    // MARK: - TableViewCellDelegate
    func use(_ cellString: String) {
        stubUse?(cellString)
    }
}

class MyTableViewTests: XCTestCase {
    func testCellString() {
        let testExpectation = expectation(description: #function)

        let expectedCurrentString = "Foo"
        let mockDelegateObject = MockDelegateObject()
        mockDelegateObject.stubUse = { cellString in
            XCTAssertEqual(expectedCurrentString, cellString)
            testExpectation.fulfill()
        }

        // Initialize your table view and do whatever you need to do to add your table view to a window, view controller, etc.
        let tableView = MyTableView()
        let sut = MyTableViewOwningObject(tableView: tableView)
        sut.delegate = mockDelegateObject

        // Do whatever it is you need to do to kick off your table view data loading/displaying, ultimately calling
        sut.loadData()

        // Tell your table view to select whichever cell you want
        let firstIndexPath = IndexPath(row: 0, section: 0)
        tableView.selectRow(at: firstIndexPath, animated: false, scrollPosition: .none)
                tableView.delegate?.tableView?(self.tableView, didSelectRowAt: firstIndexPath)

        waitForExpectations(timeout: 0.001)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.