将createColdObservable用于RxTest时,XCTAssertEqual失败

问题描述

我的测试代码中有一个奇怪的问题。我想测试视图模型中的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,(.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]")

Cleary这些事件是等效的,为什么会失败?

解决方法

我已经和你有类似的问题。

就我而言,覆盖BankViewModel.Status的Equatable 使测试失败。

请检查。在 BankViewModel.Status 层次结构中是否有一个重要的Implement Equatable协议,并且可以正确编辑。


从评论中

更新

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

请正确比较并比较Status.Save的开关lhs,rhs

enum Status: Equatable {
    case fetching,.saving),(.saveSuccess,(.failure,.failure):
            return true
        default:
            return false
        }
    }
}