Aliaksandr Kazlou
Aliaksandr Kazlou

Reputation: 3301

How to do integration testing in Clojure?

What are the techniques and libraries to do the integration testing in Clojure. Specifically interaction with databases, ring applications, core.async channels, anything which produces a side-effect.

Upvotes: 5

Views: 1676

Answers (1)

Mark Fisher
Mark Fisher

Reputation: 9886

You can use ring-mock for ring applications. An example of creating a mock handler and using it is:

(let [h (-> (POST "/some/url" [] some-resource)
            (wrap-defaults api-defaults))]
  (let [resp (h (-> (request :post "/some/url")
                    (header "content-type" "application/json")
                    (body (generate-string {:foo :bar}))))]
    (is (= 303 (:status resp)))
    (is (= "" (:body resp)))
    (is (= "http://some/place/foo" (get-in resp [:headers "Location"])))))

For d/b interation testing and side-effects, I use with-redefs to stub out the actual side-effecting function and capture and test the arguments to it are as expected. I'm not sure if this is idiomatic, but it's what I've found the easiest, e.g.

(testing "some d/b work"
  (let [insert-data (ref {})]
    (with-redefs
      [d/insert-data<! 
       (fn [db data] (dosync (alter insert-data assoc :db db)
                             (alter insert-data assoc :data data)))]
      (let [d (your-fn your-args)]
        (is (= {:some :expected-result} d))
        (is (= {:db {:some :connection-data} :data {:some :expected-data}} @insert-data))))))

You can use atoms here, historically I've had to use refs when I was testing some agents that did write-back work, and atoms didn't work in that scenario.

The main library I use is clojure.test, I only briefly dabbled with property testing using test.check so far. I used Midje for a while, but found clojure.test felt purer, but that was down to taste. Plus if you're venturing into cljs, you may as well stick with one testing framework.

I haven't any experience using core.async, but its own tests look like a good place to start.

Upvotes: 7

Related Questions