1

我有一个绑定到实例的 tableView var myStrings: BehaviorRelay<[String]>,这样 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)

我将如何测试我在单元测试中订阅 itemsSelected 时的关闭?

4

1 回答 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"

        // Create an instance of your mock object which conforms to your delegate; its spy method will get called with your cell text string when the delegate method is called in your subscription code
        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)

        // Set your object's delegate to be the mock delegate we've created which will receive messages from the subscription in your code
        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)
    }
}
于 2020-04-25T22:16:55.980 回答