RxSwift PublishSubject 单元测试

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

这是我的视图模型

import Foundation
import RxSwift

class CitiesViewModel {
    let service: CityServiceProvider
    var cities: PublishSubject<[CityDetail]> = PublishSubject()
    let errorMessage: PublishSubject<String> = PublishSubject()
    
    init(service: CityServiceProvider) {
        self.service = service
    }
    
    func getCities(completion: (() -> ())? = nil)  {
        service.getCities { result in
            switch result {
            case .success(let response):
                self.cities.onNext(response.cityList)
            case .failure(let error):
                self.errorMessage.onNext(error.localizedDescription)
            }
            completion?()
        }
    }
}

我只是想知道如何测试

cities
具有价值,而
errorMessage
在调用
getCities()
后没有价值(我将在单元测试中使用模拟服务)

这是我的单元测试

    func testSuccessfulResult() {
        let expectation = self.expectation(description: #function)
        let service = MockCityServiceWithSuccessResponse()
        let viewModel = CitiesViewModel(service: service)

        viewModel.getCities(completion: {
            expectation.fulfill()
        })
        
        viewModel.cities.subscribe { details in
            // This body will never execute
            guard let details = details.element else {
                XCTFail("Details is empty")
                return
            }
            XCTAssertTrue(details.count > 0, "Load details successfully")
        }.disposed(by: DisposeBag())
        
        wait(for: [expectation], timeout: 2)
    }
unit-testing publish-subscribe rx-swift
2个回答
0
投票

您正在订阅

cities
after 价值已发出并满足期望。将您的订阅移至 getCities 调用之前,您应该会看到成功。

还有:

  • cities
     不应该是 
    var
    。所有主题应始终为 
    let
     常量。
  • 您的视图模型不应暴露主题。将主题设为私有并公开 Observable。 (否则,任何人都可以将价值观强加到主题中。)

0
投票
不是要回答这个问题,但我也注意到你在

self

代码块中强烈引用
service.getCities { result in ... }
,这会导致内存问题

© www.soinside.com 2019 - 2024. All rights reserved.