首页 > 解决方案 > 如何在 Swift 中控制单元测试的随机性?

问题描述

我想RandomNumberGenerator为我的班级注入一个以编写单元测试。但是,似乎接收随机数生成器的方法仅适用于具体类型。

意思就是

var rng: RandomNumberGenerator = SystemRandomNumberGenerator()
Bool.random(using: &rng)

不编译,报错:

在参数类型中inout RandomNumberGeneratorRandomNumberGenerator不符合预期类型RandomNumberGenerator

var rng = SystemRandomNumberGenerator()
Bool.random(using: &rng)

做。

问题是我想在运行我的应用程序时使用默认的随机数生成器,并使用我控制的自定义随机数生成器进行测试。为了在 Swift 中制作可测试的代码,控制随机性的一般方法是什么?

标签: swift

解决方案


从这个protocol-doesnt-conform-to-itself,我使用了“构建类型橡皮擦”的答案

    struct AnyRandomNumberGenerator: RandomNumberGenerator {
       private var generator: RandomNumberGenerator

       init(_ generator: RandomNumberGenerator) {
           self.generator = generator
       }

       mutating func next() -> UInt64 {
           return self.generator.next()
       }


       public mutating func next<T>() -> T where T : FixedWidthInteger, T : UnsignedInteger {
        return self.generator.next()
       }


       public mutating func next<T>(upperBound: T) -> T where T : FixedWidthInteger, T : UnsignedInteger {
            return self.generator.next(upperBound: upperBound)
      }

}

那么它可以像这样使用

    var randomNumberGenerator: RandomNumberGenerator = SystemRandomNumberGenerator()
    var random = AnyRandomNumberGenerator(randomNumberGenerator)
    UInt8.random(in: .min ... .max, using: &random)

推荐阅读