如何解决我们如何测试生成随机状态且不能两次生成相同状态的类?
我们有三个状态。我们如何测试(使用单元测试)我们的类每 5 秒生成一次随机状态,并且不能连续两次生成相同的状态?我们的随机生成器类的代码如下 ` 最终类 StaterandomGenerator: RandomGeneratorProtocol { 私有变量 sourceObservable:一次性? private(set) var prevIoUsValue: Int? var generateValue: PublishSubject = PublishSubject()
init(_ interval: RxTimeInterval,_ scheduler: SchedulerType = MainScheduler.instance) {
sourceObservable = Observable<Int>
.interval(interval,scheduler: scheduler)
.flatMap { [uNowned self] _ in self.generaterandom()}
.compactMap { state in
return state?.description
}
.subscribe(onNext: { [weak self] description in
self?.generatedValue.onNext(description)
})
}
func generaterandom() -> Observable<ConnectionState?> {
return Observable.create { [weak self] observer in
var randomNumber = Int.random(in: 0..<ConnectionState.count)
guard let prevIoUsValue = self?.prevIoUsValue else {
let value = ConnectionState(rawValue: randomNumber)
self?.prevIoUsValue = randomNumber
observer.onNext(value)
return disposables.create()
}
while randomNumber == prevIoUsValue {
randomNumber = Int.random(in: 0..<ConnectionState.count)
}
self?.prevIoUsValue = randomNumber
let value = ConnectionState(rawValue: randomNumber)
observer.onNext(value)
return disposables.create()
}
}
enum ConnectionState: Int {
case error
case connecting
case established
var description: String {
switch self {
case .connecting:
return "It is connecting"
case .error:
return "There is an error"
case .established:
return "Thе connection is established"
}
}
} `
解决方法
您无法成功地对您的课程进行单元测试,因为它不会停止。它只是固定 CPU 并占用内存,直到系统最终饿死并崩溃。
下面是一个可以运行并经过测试的 Observable,它可以执行您想要的操作……该测试创建了 100,000 个 ConnectionStates,然后检查以确保没有两个相邻的节点是相同的。
函数的主要逻辑是传递给 map
的闭包,它抓取所有案例并过滤掉之前的案例。从余数中随机选择一个元素。
在我期望的任何枚举中都可以很容易地做到这一点。我将把它留给读者作为练习。
func stateRandom(_ interval: RxTimeInterval,_ scheduler: SchedulerType = MainScheduler.instance) -> Observable<ConnectionState> {
let previous = BehaviorRelay<ConnectionState?>(value: nil)
return Observable<Int>.interval(interval,scheduler: scheduler)
.withLatestFrom(previous)
.map { ConnectionState.allExcept($0) }
.flatMap { Observable.just($0.randomElement()!) }
.do(onNext: { previous.accept($0) })
}
extension CaseIterable where Self: Equatable {
static func allExcept(_ value: Self?) -> [Self] {
allCases.filter { $0 != value }
}
}
enum ConnectionState: CaseIterable,Equatable {
case error
case connecting
case established
}
class Tests: XCTestCase {
func test() throws {
let scheduler = TestScheduler(initialClock: 0)
let result = scheduler.start { stateRandom(.seconds(1),scheduler).take(100000) }
for (prev,current) in zip(result.events,result.events.dropFirst()) {
XCTAssertNotEqual(prev.value,current.value)
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。