4

在使用 test.check 时,我需要一个生成器来生成一定长度的字符串。电话号码、邮政编码、社会安全号码都是此类数据的示例。尽管这些示例似乎只是数字,但我的问题是一般的字符串。

4

3 回答 3

7

鉴于length下面的生成器生成随机字符串:

(gen/fmap #(apply str %) 
          (gen/vector gen/char-alpha length))

(gen/vector gen/char-alpha length)生成字符序列fmap并将它们转换为字符串:

(apply str [\a \b]) ;; => "ab"

如果需要自定义alphabet(比如说[\a \b \c]),gen/char-alpha可以用类似的东西代替:

(gen/elements alphabet)

对于更复杂的生成器,例如格式化的电话号码,test.chuckstring-from-regex可能是比手动组合官方生成器更好的选择。

于 2016-03-13T18:28:32.440 回答
2

您可以使用更原始的生成器来快速构建一个可以做到这一点的生成器:

对于 min 和 max 之间的字母数字字符串:

(sgen/fmap str/join (sgen/vector (sgen/char-alphanumeric) min max))

对于给定长度的字母数字字符串

(sgen/fmap str/join (sgen/vector (sgen/char-alphanumeric) length))

您可以(sgen/char-alphanumeric)根据您的字符范围需要进行相应修改,例如带有字母数字和下划线以及破折号字符的最小/最大值字符串,每个字符的显示频率不同:

(sgen/fmap str/join
                (sgen/vector
                 (sgen/frequency [[99 (sgen/char-alphanumeric)]
                                  [1 (sgen/elements #{"_" "-"})]])
                 min max))
于 2019-11-12T21:04:44.867 回答
1

此函数将生成一个给定长度的字符串,其中包含给定字母表中的字符(可选)。如果您不传递任何字母作为参数,则将使用默认值,您当然可以更改它。

(defn generate-string 
  ([length]
   (generate-string length
            (map char (range 49 127))))
  ([length alphabet]
   (apply str (take length (repeatedly #(rand-nth alphabet))))))

例子:

(generate-string 7 [\a \b \c])
"bacacbb"

(generate-string 10)
"mxqE<OKH3L"
于 2016-03-13T17:47:42.910 回答