1

I have created tableView with sections by RxDataSources.

ViewController

viewModel.sectionsObservable
        .bindTo(tableView.rx.items(dataSource: viewModel.dataSource))
        .disposed(by: disposeBag)

sectionsObservable emits the event when a new element is added to the array.

I would like to test if a proper element is on proper indexPath.

func testGettingElementForIndexPath() {
    let element = Element()
    viewModel.addElement(element)
    let fetchedElement = viewModel.getElement(at: IndexPath(row: 0, section: 0))
    XCTAssertEqual(element, fetchedElement)
}

ViewModel

func getElement(at indexPath: IndexPath) -> Element {
    return self.dataSource.sectionModels[indexPath.section].items[indexPath.row]
}

it works in the app, but tests fail. fatal error: Index out of range

It's all because of that asynchronous. How to test this case?


EDIT 1: ViewModel

let elementsVariable = Variable<[TaskData]>([])
func addElement(_ element: Element) {
    elementsVariable.value.append(element)
}

var sectionsObservable: Observable<[Day]> {
    return elementsVariable.asObservable().map { (elements) -> [MySection] in
        ...
    }
}
Adam Smaka
  • 5,977
  • 3
  • 50
  • 55

1 Answers1

0

If you say that the production code works fine it has to be some silly mistake.

In production code you have:

.bindTo(tableView.rx.items(dataSource: viewModel.dataSource))

which internally sets items inside the dataSource

Check if you also have it inside the test code

Adam Borek
  • 26
  • 1
  • 3
  • I think dataSource.sectionModels doesn't have enough time to become updated and XCTAssert runs faster async – Adam Smaka Mar 14 '17 at 21:56
  • Do you change a `scheduler` somewhere? If not I think it is not a case here. But maybe... – Adam Borek Mar 15 '17 at 05:16
  • If it so I would say is a problem with architecture design. Methods like `addElement` `getElement` are reactive code smell (because they are not reactive but imperative) :( However, you haven't answered my question yet :D. Do you subscribe for `viewModel.dataSource` somewhere inside the test code? – Adam Borek Mar 15 '17 at 05:23
  • 1
    I'll create some demo locally on the weekend and try to play with it. Is hard to help you without the code in front of me :P – Adam Borek Mar 17 '17 at 06:30