Refactoring techniques to turn your Clojure code into an onion
WORK IN PROGRESS
Separate calculations from side-effects
Flatten deep call trees
Declarative queries
Declarative effects
(defn update-customer-email [customer-id new-email]
(let [customer (-> (db/load-customer customer-id) ;; I/O
(assoc :email (str/trim new-email))];; calculation
(db/save-customer customer))) ;; I/O
# PRESENTING CODE
How to test this?
(deftest test-update-customer-email []
(with-redefs [db/load-customer (constantly {:name "Han Solo" :email "han@solo.net"})
db/save-customer #(is (= "han.solo@rebels.net" (:email %1))]
(update-customer-email "id" "han.solo@rebels.net"))))
Not a good test. It can't treat `update-customer-email` as a black-box and needs to understand what to re-define.
If `update-customer-email` uses a different `db` fn, the test will break.