Jochen Bedersdorfer
Software Engineer
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
(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
(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
(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"))))
(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"))))
(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"))))
(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.
By Jochen Bedersdorfer