请在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]))

(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-gen 作为 `::y` 的生成器

(try
  (stest/instrument `do-y {:stub #{`do-y}
                           :gen {::y (fn [] y-gen)}})
  (catch Exception e
    (ex-data e)))
;; => #: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
                                                        (fn [] y-gen))))}})
;; => [spec-ex.core/do-y]

1 答案

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