Using spec instrument to stub functions is really helpful. I'm using stubbing
to test Stuart Sierra-style components with some success. However, I've been
surprised that generator override doesn't work as I would expect it to. Here's
an example:
;; [org.clojure/spec.alpha "0.1.123"]
(require '[clojure.spec.alpha :as s])
(require '[clojure.spec.gen.alpha :as gen])
(require '[clojure.spec.test.alpha :as stest])
(defprotocol Y
(-do-y [r]))
(def y? (partial satisfies? Y))
(s/def ::y y?)
;; Protocol methods can't be spec'd, so wrap it in a function.
(defn do-y [r]
(-do-y r))
(s/fdef do-y :args (s/cat :y-er ::y))
;; Example of the protocol implementation that we're going to stub.
(defrecord BadYer []
Y
(-do-y [_] (throw (Exception. "can't make me!"))))
;; Confirm BadYer instances are valid with respect to the protol spec.
(s/valid? ::y (->BadYer))
;; => true
;; And confirm BadYer instances will throw when called.
(try
(do-y (->BadYer))
(catch Exception e
(.getMessage e)))
;; => "can't make me!"
(def y-gen (gen/return (->BadYer)))
;; Confirm generator works as expected:
(gen/sample y-gen 1)
;; => (#spec_ex.core.BadYer{})
;; We want to stub `do-y`, providing y-gen as a generator for `::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}
;; However, we *can* stub `do-y` if we replace its spec.
(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]
There is a ticket open[ (CLJ-2095[1]) regarding using overrides s/gen with
custom generators. Is this a case where this applies? I can imagine that it
could be. Not overriding something that isn't there would result in the thing
still not being there, thus the :no-gen failure. And it is something that can
be worked around. It would be decidedly more succinct if the gen override
worked rather than the spec override.
Best,
Michael Glaesemann
grzm seespotcode net
[1]: https://dev.clojure.org/jira/browse/CLJ-2095
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.