Как я могу имитировать выбор строки tableView с помощью RxSwift - PullRequest
1 голос
/ 19 марта 2019

У меня есть 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)
    }

Но это не удается, за исключением

отправлено нераспознанное селекторное сообщениек примеру

Как мне смоделировать выбранную строку в моем модульном тесте?

1 Ответ

2 голосов
/ 19 марта 2019

Короткий ответ - нет.Модульные тесты не являются местом для объектов UIView и манипулирования объектами UI.Вы хотите добавить цель тестирования пользовательского интерфейса для такого рода тестов.

...