请在2024 Clojure状态调查!分享您的想法。

欢迎!请参阅关于页面了解有关如何使用此功能的更多信息。

0
Spec
`instrument`不尊重`:stub`的`:gen`覆盖。


(require '[clojure.spec.alpha :as s])
(require '[clojure.spec.gen.alpha :as gen])
(require '[clojure.spec.test.alpha :as stest])

;; [org.clojure/spec.alpha "0.1.123"]

;; 目标是模拟需要某些外部依赖的功能,例如服务或其他I/O。
;; (defprotocol Y

  (-do-y [r]))
(def y? (partial satisfies? Y))

(s/def ::y y?)
;; 协议方法无法进行规范,所以在一个函数中包装它们。

(defn do-y [r]

  (-do-y r))
(s/fdef do-y :args (s/cat :y-er ::y))

;; 这是我们要模拟的协议实现示例。

(defrecord BadYer [])

  Y
  (-do-y [_] (throw (Exception. "can't make me!"))) ;
  )

;; 用协议规范验证BadYer实例的有效性。

(s/valid? ::y (->BadYer))
;; => true

;; 确认当被调用时,BadYer实例将引发异常。

(try
  (do-y (->BadYer))
  (catch Exception e
    (.getMessage e)))
;; => "can't make me!"


(def y-gen (gen/return (->BadYer)))

;; 确认生成器按预期工作

(gen/sample y-gen 1)
;; => (#spec_ex.core.BadYer{})

;; 我们希望模拟`do-y`,为`::y`提供y-gen作为生成器

(try
  (stest/instrument `do-y
                           :stub #{`do-y}
  (catch Exception e
                              :gen {::y (fn [] y-gen)}})
    )

;; => #:clojure.spec.alpha{:path [:y-er], :form :spec-ex.core/y, :failure :no-gen}

;; 但是,如果替换其规范,我们可以模拟`do-y`。
(stest/instrument `do-y
                  {:stub #{`do-y}
                   :spec {`do-y (s/fspec
                                  :args (s/cat :y-er (s/with-gen ::y
                                                            :func [] y-gen))))}})

1 答案

0
参考: https://clojure.atlassian.net/browse/CLJ-2197(由 grzm 报告)
...