将 createColdObservable 用于 RxTest 时 XCTAssertEqual 失败
XCTAssertEqual fails when using createColdObservable for 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]")
显然这些事件是等价的,那么为什么会失败?
我已经遇到过类似的问题。
在我的例子中,覆盖 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.saving的开关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
}
}
}
我的测试代码中有一个奇怪的问题。我想在我的视图模型中测试 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]")
显然这些事件是等价的,那么为什么会失败?
我已经遇到过类似的问题。
在我的例子中,覆盖 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.saving的开关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
}
}
}