给定这种情况,调用 fspec 将失败
(def uuid-regex #"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$")
(s/def ::name string?)
(s/def ::age pos-int?)
(s/def ::id (s/and string? #(re-matches uuid-regex %)))
(s/def ::person (s/keys :req-un [::name ::age ::id]))
;; 有效 - ::id 生成器覆盖生成有效的 IDs
(s/exercise ::person 1 {::id (fn [] (gen/fmap str (gen/uuid)))})
;; 失败 - ::id 生成器覆盖未被使用
(s/exercise
(s/fspec :args (s/cat :p ::person) :ret int?)
10
{::id #(gen/fmap str (gen/uuid))})
在 100 次尝试后无法满足 such-that 断言。
**问题**:exercise 生成了一个验证参数并返回 gen int 的函数。当 exercise 对生成的 fspec 函数进行相容性验证时,它会调用 fspec-impl 中的 conform。fspec-impl 中的 conform* 调用 validate-function。validate-function 在生成的函数上运行快速检查,但 conform* 和 validate-function 无法访问 exercise 中指定的生成器覆盖。如果您在运行类似于使用 fspec (如具有 fspec 参数的 fdef) 的任何内容时运行 stest/check,也会发生相同的问题。