Сбой XCTAssertEqual при использовании createColdObservable для RxTest

#swift #rx-swift #xctest #rxtest

#swift #rx-swift #xctest #rxtest

Вопрос:

У меня странная проблема в моем тестовом коде. Я хочу протестировать BehaviourRelay , на мой взгляд, изменение модели со статуса .fetching на .saving . У меня есть следующий тестовый код:

 class BankViewModelTests: XCTestCase {
    
    private var scheduler: TestScheduler!
    private var bag: DisposeBag!
    private var user: UserModel!
    

    override func setUpWithError() throws {
        try! super.setUpWithError()
        
        let url = Bundle(for: type(of: self)).url(forResource: "User", withExtension: "json")!
        let jsonData = try! Data(contentsOf: url)
        let jsonDict = try! JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) as! JSONDictionary
        user = UserModel(jsonDict)!
        
        scheduler = TestScheduler(initialClock: 0)
        bag = DisposeBag()
    }

    override func tearDownWithError() throws {
        user = nil
        scheduler = nil
        bag = nil
        try! super.tearDownWithError()
    }
    
}

extension BankViewModelTests {
    func testSavingStatus() {
        // Arrange
        
        let sut = BankViewModel(user: user)
        
        let status = scheduler.createObserver(BankViewModel.Status.self)
        sut.status.bind(to: status).disposed(by: bag)
        
        // Action
        
        scheduler.createColdObservable([.next(10, ())]).bind(to: sut.tappedSubmit).disposed(by: bag)
        
        scheduler.start()
        
        // Assert
        
        XCTAssertEqual(status.events, [
            .next(0, .fetching),
            .next(10, .saving)
        ])
    }
    
}
  

Мое Status перечисление выглядит так:

 enum Status: Equatable {
    case fetching, fetchSuccess, saving, saveSuccess, failure(Error)

    public static func == (lhs: Status, rhs: Status) -> Bool {
        switch (lhs, rhs) {
        case (.fetching, .fetching),
             (.fetchSuccess, .fetchSuccess),
             (.saving, .saveSuccess),
             (.failure, .failure):
            return true
        default: return false
        }
    }
}
  

Когда я запускаю тест, я получаю следующее сообщение: XCTAssertEqual failed: ("[next(fetching) @ 0, next(saving) @ 10]") is not equal to ("[next(fetching) @ 0, next(saving) @ 10]")

Ясно, что эти события эквивалентны, так почему это сбой?

Ответ №1:

У меня уже была подобная проблема с вами.

В моем случае переопределение Equatable для BankViewModel .Сбой проверки состояния.

Пожалуйста, проверьте. Существует ли переопределяющий протокол Equatable в BankViewModel.Иерархия состояний и корректное редактирование.


Обновлено из комментариев

 enum Status: Equatable {
    case fetching, fetchSuccess, saving, saveSuccess, failure(Error)

    public static func == (lhs: Status, rhs: Status) -> Bool {
        switch (lhs, rhs) {
        case (.fetching, .fetching),
             (.fetchSuccess, .fetchSuccess),
             (.saving, .saveSuccess), // <- (.saving == .saving) always false so test make fail
             (.failure, .failure):
            return true
        default: return false
        }
    }
}

XCTAssertEqual(Status.saving, Status.saving) // Now, It should be failed because overriding Equatable implement
  

Пожалуйста, сопоставьте и сравните значения lhs коммутатора, rhs состояния.сохранение правильно

 enum Status: Equatable {
    case fetching, fetchSuccess, saving, saveSuccess, failure(Error)

    public static func == (lhs: Status, rhs: Status) -> Bool {
        switch (lhs, rhs) {
        case (.fetching, .fetching),
             (.fetchSuccess, .fetchSuccess),
             (.saving, .saving),
             (.saveSuccess, .saveSuccess),
             (.failure, .failure):
            return true
        default:
            return false
        }
    }
}
  

Комментарии:

1. Я не совсем уверен, что вы имеете в виду. Я отредактировал свой вопрос и добавил код для Status . Я внедряю Equatable . Я что-то упустил?

2. @Kex в вашей реализации Equatable возвращает false, если compare .saving == .saving

3. Спасибо за ваш ответ. Я пропустил это