Sometimes you run into some functionality that you want to implement, but it’s just a little bit out of reach. Maybe it’s something behind an API, database, or a larger function that you don’t necessarily care about.

Today I ran into a similar issue–I wanted to add functionality to an HTML renderer, but didn’t want to create my tests around the actual HTML rendering function. I knew if I did that, I end up having DOM calls in every test to make sure my function did what it was supposed to.

Let’s say I have this function and I want to change the way the tag name (createDom’s first parameter) is selected.

(defn hiccup->html [hiccup]
  (createDom (subs (first (str hiccup)) 1) (clj->js (second hiccup))))

This function depends on createDom, which is in some HTML DOM library and is quite a bit of trouble to set up. In addition to setup, I’ll need to select the tag name from the return value for each test! Well that’s a lot of work, and I’m really lazy.

One way we can get around this is to create a new function, tag-name, and test that instead!

(defn tag-name [hiccup] 
  )
(defn hiccup->html [hiccup]
  (createDom (subs (first (str hiccup)) 1) (clj->js (second hiccup))))

Before we start using tag-name in our higher level function, we want to at least implement the existing functionality so that our higher level function does not break.

; spec
(describe "tag-name"
  (it "is parsed as an h1"
    (should= "h1" (tag-name [:h1])))
  (it "is parsed as a div"
    (should= "div" (tag-name [:div]))))
; src
(defn tag-name [hiccup]
  (subs (first (str hiccup)) 1))
(defn hiccup->html [hiccup]
  (createDom (subs (first hiccup) 1) (clj->js (second hiccup))))

At this point, we can refactor hiccup->html to use tag-name, and continue to test new features under the tag-name function.

(defn tag-name [hiccup]
  (subs (first (str hiccup)) 1))
(defn hiccup->html [hiccup]
  (createDom (tag-name hiccup) (clj->js (second hiccup))))

This keeps our tests focused and decluttered from irrelevant information. After all, we only care about how tag names are selected–not how the DOM is rendered. Although it wouldn’t be a bad idea to make sure tests already exist around the higher-level function.