2
votes

Is there a clean way of adding spec generators in test code that apply to a spec defined in another source file? For example, say I have the following under my main src/ directory:

(s/fdef my-func
   :args (s/cat 
           :statement (partial instance? java.sql.PreparedStatement))
   :ret bool?)

In order to do generative testing I will need a generator for the statement argument, say one that generates mock statements, but I'd rather not mix test code with production nor make other projects that use this library also transitively pull down the test libraries.

So what I'm looking for is a convention to apply generators atop an existing spec without having to modify the source for that spec.

1
Since specs use a global registry, writing your spec last most likely is the way to gocfrick

1 Answers

2
votes

clojure.spec.test.alpha/check takes an optional map of generator overrides: https://clojure.github.io/spec.alpha/clojure.spec.test.alpha-api.html#clojure.spec.test.alpha/check

:gen        map from spec names to generator overrides

Note that you need to use a named spec, so in your example above you'd need to s/def something like ::statement:

(s/def ::statement (partial instance? java.sql.PreparedStatement))

Then your function spec :args would look like (s/cat :statement ::statement).

You could then supply a generator to check like this in your test project:

(st/check sym-or-syms {:gen {::statement my-test-proj-generator}})

a convention to apply generators atop an existing spec without having to modify the source for that spec

I think with-gen is appropriate for this: it takes an existing spec and returns that spec with a given generator.