RxTest - 如何比较 Event<Void> 因为 Void 不是 Equatable
RxTest - How to compare Event<Void> as Void is not Equatable
ViewModel 有一个输入(观察者),它绑定到 UIViewController
中 UIButton
的 tap
事件。这个观察者的类型是 AnyObserver<Void>
.
在我的单元测试中,这是我所期望的:
let correctValues: [Recorded<Event<Void>>] = Recorded.events(
.next(0, ()),
.completed(0)
)
我的测试观察者定义是:
private var voidEventsObserver: TestableObserver<Void>!
let scheduler = TestScheduler(initialClock: 0)
voidEventsObserver = scheduler.createObserver(Void.self)
断言语句:
XCTAssertEqual(voidEventsObserver.events, correctValues)
我收到以下错误:
Expression type '()' is ambiguous without more context
在 Rx 中,Void
事件是正常的,要正确测试 ViewModel,需要比较它们。例如.next(0, ())
、.completed(0)
等 Void
不是 Equatable
并且使它成为 Equatable
没有任何意义。但是,我需要断言事件是 .next
或 .error
或 .completed
。我如何断言该部分?
与 Void
一起工作有时会很痛苦。
试过你的例子,但是由于 Void
不是标称类型或由于这些类型已经与 Equatable
.
相冲突
一种方法是做这样的事情:
XCTAssertEqual(voidEventsObserver.events.count, correctValues.count)
for (actual, expected) in zip(voidEventsObserver.events, correctValues) {
XCTAssertEqual(actual.time, expected.time, "different times")
let equal: Bool
switch (actual.value, expected.value) {
case (.next, .next),
(.completed, .completed):
equal = true
default:
equal = false
}
XCTAssertTrue(equal, "different event")
}
现在这太丑陋了,难以阅读。另一种方法是引入包装器:
struct VoidRecord: Equatable {
let record: Recorded<Event<Void>>
static func == (lhs: Self, rhs: Self) -> Bool {
guard lhs.record.time == rhs.record.time else { return false }
switch (lhs.record.value, rhs.record.value) {
case (.next, .next),
(.completed, .completed):
return true
default:
return false
}
}
}
XCTAssertEqual(
voidEventsObserver.events.map(VoidRecord.init),
correctValues.map(VoidRecord.init)
)
读起来好多了。请注意,上面将 .error
事件视为始终不同。如果您需要比较错误事件,只需将 RxSwift 中的 this logic 添加到上面的 ==
函数即可。
ViewModel 有一个输入(观察者),它绑定到 UIViewController
中 UIButton
的 tap
事件。这个观察者的类型是 AnyObserver<Void>
.
在我的单元测试中,这是我所期望的:
let correctValues: [Recorded<Event<Void>>] = Recorded.events(
.next(0, ()),
.completed(0)
)
我的测试观察者定义是:
private var voidEventsObserver: TestableObserver<Void>!
let scheduler = TestScheduler(initialClock: 0)
voidEventsObserver = scheduler.createObserver(Void.self)
断言语句:
XCTAssertEqual(voidEventsObserver.events, correctValues)
我收到以下错误:
Expression type '()' is ambiguous without more context
在 Rx 中,Void
事件是正常的,要正确测试 ViewModel,需要比较它们。例如.next(0, ())
、.completed(0)
等 Void
不是 Equatable
并且使它成为 Equatable
没有任何意义。但是,我需要断言事件是 .next
或 .error
或 .completed
。我如何断言该部分?
与 Void
一起工作有时会很痛苦。
试过你的例子,但是由于 Void
不是标称类型或由于这些类型已经与 Equatable
.
一种方法是做这样的事情:
XCTAssertEqual(voidEventsObserver.events.count, correctValues.count)
for (actual, expected) in zip(voidEventsObserver.events, correctValues) {
XCTAssertEqual(actual.time, expected.time, "different times")
let equal: Bool
switch (actual.value, expected.value) {
case (.next, .next),
(.completed, .completed):
equal = true
default:
equal = false
}
XCTAssertTrue(equal, "different event")
}
现在这太丑陋了,难以阅读。另一种方法是引入包装器:
struct VoidRecord: Equatable {
let record: Recorded<Event<Void>>
static func == (lhs: Self, rhs: Self) -> Bool {
guard lhs.record.time == rhs.record.time else { return false }
switch (lhs.record.value, rhs.record.value) {
case (.next, .next),
(.completed, .completed):
return true
default:
return false
}
}
}
XCTAssertEqual(
voidEventsObserver.events.map(VoidRecord.init),
correctValues.map(VoidRecord.init)
)
读起来好多了。请注意,上面将 .error
事件视为始终不同。如果您需要比较错误事件,只需将 RxSwift 中的 this logic 添加到上面的 ==
函数即可。