I'm just getting started with unit testing in clojure (I've done some in JS and C#) and I'm wondering about something I'm not quite sure how to phrase. So in FP we build small pure functions and other functions build on those, etc. So I'm wondering if our tests should call the chain of functions we also have tests for in creating the expected value, or if the expected value should always be the output of those sub functions. Let me give an example of what I'm working with. One moment.
Now for the second, do I make the expected value the entire output (map) of calling build-get-request
or do I call build-base-request
and merge the added key value pairs onto it to make the expected value or do I explicitly give it the entire expected output? Not sure if I'm being clear...
To be honest, these are small enough and simple enough that I probably wouldn't bother writing unit tests for them.
Well, I have more complex cases that build on those.
I might write specs for the data, tho' (and then possibly a couple of property-based tests based on the functions).
I see. I'll do more reading about property-based tests as I'm new to clojure testing in general. Btw, thanks for your work on expectations. 👍
Glad you like it 🙂
Much better output for failures
Yes, unfortunately I've had to sacrifice some of that with the clojure.test
integration in Expectations. Hoping to bring it back at some point. But tooling, such as #cursive has a lot of expectations of clojure.test
output so I'm still hammocking some of that...
Going to back to your comment about "small pure functions" -- that's why a lot of the small stuff in Clojure really doesn't need tests: many of the functions are very simple and obviously correct by inspection.
There are many ways to write correct-by-inspection-but-horribly-wrong-in-a-corner-case functions.
Especially dealing with numbers.
@dottedmag Fair point, and with actual computation, yes, I'd want at least some boundary tests or property tests.
@brandon.ringe Since you're using Expectations, I'd suggest something like:
(expect (more-of {:keys [url] :as data}
{:method "GET" :accept :json :as :json} (in data)
string? url)
(from-each [url ["<http://foo.com>" "<https://google.com>"]]
(build-get-request url)))
as a more general testI see.
That gets you closer to what a property-based test, using test.check
, might look like: isolate the invariant part from the rest.
If you had generatable specs for method and URL, you could use s/exercise
to generate random, but compliant, test data as a next step.
(overkill for these simple functions but steps toward property-based testing for more complex stuff)
Interesting. I have not even gotten into spec yet. This is my first clojure project. I have much to learn.
"Always Be Learning" 🙂
I started learning Clojure back in 2010 and have been using it in production since 2011 -- and I'm forever learning new stuff!