首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >RxSwift,使用RxBlocking的测试不会结束

RxSwift,使用RxBlocking的测试不会结束
EN

Stack Overflow用户
提问于 2018-05-07 15:11:09
回答 1查看 2.1K关注 0票数 1

我正在尝试测试一个非常简单的视图模型:

代码语言:javascript
运行
复制
struct SearchViewModelImpl: SearchViewModel {
    let query = PublishSubject<String>()
    let results: Observable<BookResult<[Book]>>

    init(searchService: SearchService) {
        results = query
            .distinctUntilChanged()
            .throttle(0.5, scheduler: MainScheduler.instance)
            .filter({ !$0.isEmpty })
            .flatMapLatest({ searchService.search(query: $0) })
    }
}

我正试着测试从服务处接收一个错误,所以我用这种方式加倍了它:

代码语言:javascript
运行
复制
class SearchServiceStub: SearchService {
    let erroring: Bool

    init(erroring: Bool) {
        self.erroring = erroring
    }

    func search(query: String) -> Observable<BookResult<[Book]>> {
        if erroring {
            return .just(BookResult.error(SearchError.downloadError, cached: nil))
        } else {
            return books.map(BookResult.success) // Returns dummy books
        }
    }
}

我正在测试这样一个错误的查询:

代码语言:javascript
运行
复制
func test_when_searchBooksErrored_then_nextEventWithError() {
    let sut = SearchViewModelImpl(searchService: SearchServiceStub(erroring: true))
    let observer = scheduler.createObserver(BookResult<[Book]>.self)

    scheduler
        .createHotObservable([
            Recorded.next(200, ("Rx")),
            Recorded.next(800, ("RxSwift"))
        ])
        .bind(to: sut.query)
        .disposed(by: disposeBag)

    sut.results
        .subscribe(observer)
        .disposed(by: disposeBag)

    scheduler.start()

    XCTAssertEqual(observer.events.count, 2)
}

首先,我只是断言事件的计数是否正确,但我只收到了一个,而不是两个。我认为这是异步问题,所以我将测试更改为使用RxBlocking:

代码语言:javascript
运行
复制
func test_when_searchBooksErrored_then_nextEventWithError() {
    let sut = SearchViewModelImpl(searchService: SearchServiceStub(erroring: true))
    let observer = scheduler.createObserver(BookResult<[Book]>.self)

    scheduler
        .createHotObservable([
            Recorded.next(200, ("Rx")),
            Recorded.next(800, ("RxSwift"))
        ])
        .bind(to: sut.query)
        .disposed(by: disposeBag)

    sut.results.debug()
        .subscribe(observer)
        .disposed(by: disposeBag)

    let events = try! sut.results.take(2).toBlocking().toArray()

    scheduler.start()

    XCTAssertEqual(events.count, 2)
}

但这件事永远不会结束。

我不知道我的存根有什么问题,或者视图模型有问题,但是生产应用程序工作正常,在查询触发时发出事件。

RxTest和RxBlocking的文档非常简短,有字符串或整数的经典示例,但与这种流无关.这很令人沮丧。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-07 16:22:24

您使用MainScheduler.instance调度程序控制查询。试着移除它,看看会发生什么。这可能就是你唯一得到一个的原因。在测试时,您需要将测试调度程序注入到油门中。

要让正确的调度程序进入您的模型,有几种不同的方法。根据您当前的代码,依赖注入可以正常工作。

代码语言:javascript
运行
复制
struct SearchViewModelImpl: SearchViewModel {
    let query = PublishSubject<String>()
    let results: Observable<BookResult<[Book]>>

    init(searchService: SearchService, scheduler: SchedulerType = MainScheduler.instance) {
        results = query
            .distinctUntilChanged()
            .throttle(0.5, scheduler: scheduler)
            .filter({ !$0.isEmpty })
            .flatMapLatest({ searchService.search(query: $0) })
    }
}

那么在你的测试中:

代码语言:javascript
运行
复制
let sut = SearchViewModelImpl(searchService: SearchServiceStub(erroring: true), scheduler: testScheduler)

另外,可以将结果事件绑定到toBocking(),而不是使用testable Observer

代码语言:javascript
运行
复制
func test_when_searchBooksErrored_then_nextEventWithError() {
    let sut = SearchViewModelImpl(searchService: SearchServiceStub(erroring: true), scheduler: testScheduler)
    let observer = scheduler.createObserver(BookResult<[Book]>.self)

    scheduler
        .createHotObservable([
            Recorded.next(200, ("Rx")),
            Recorded.next(800, ("RxSwift"))
        ])
        .bind(to: sut.query)
        .disposed(by: disposeBag)

    sut.results.bind(to: observer)
     .disposed(by: disposeBag)

    scheduler.start()

    XCTAssertEqual(observer.events.count, 2)
}

虽然toBlocking()在某些情况下可能很有用,但是当您将事件绑定到testableObserver时会得到更多的信息。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50217376

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档