Testing with clojure.test
Other tools: Kaocha (feature-rich test runner, watch mode, plugins), matcher-combinators (expressive assertions for nested data), eftest (parallel runner), and etaoin (browser automation).
;; test/myapp/orders_test.clj
(ns myapp.orders-test
(:require [clojure.test :refer [deftest is are testing use-fixtures]]
[myapp.orders :as orders]))
(deftest total-test
(testing "empty order"
(is (= 0 (orders/total []))))
(testing "single item"
(is (= 10 (orders/total [{:price 10 :qty 1}]))))
(testing "throws on invalid data"
(is (thrown? IllegalArgumentException (orders/total nil)))
(is (thrown-with-msg? clojure.lang.ExceptionInfo #"Invalid" (orders/validate! {})))))
(deftest arithmetic
(are [x y expected] (= expected (+ x y)) ; table-driven tests
1 2 3
0 0 0
-1 1 0))
;; Fixtures: setup/teardown around each test or once per namespace
(defn with-db [f]
(let [db (start-test-db)]
(try (binding [*db* db] (f))
(finally (stop-test-db db)))))
(use-fixtures :each with-db)
;; Mocking with with-redefs
(deftest fetch-test
(with-redefs [orders/fetch-remote (fn [_] {:status :ok})]
(is (= :ok (:status (orders/sync! 1))))))clj -X:test # cognitect test-runner
lein test
bb test # with Babashka tasks