2012-04-30 66 views
3

背景重新定義使用Clojure + Midje

我是新來的Clojure所以請原諒任何明顯的錯誤的宏操作。我試圖測試一些使用redis-clojure庫的Clojure數據訪問代碼。雖然我的集成測試當然會測試整個堆棧,但我不希望我的單元測試依賴於連接到redis服務器實例。用Midje嘲弄實際的Redis命令似乎是相對直接的,但是連接宏更難處理。

建議需要

似乎什麼不能做或發現通過Midje文檔嘲諷Redis的連接或重新定義宏的方式。從core.clj相關頂層連接宏是:

(defmacro with-server 
    "Evaluates body in the context of a connection to Redis server 
    specified by server-spec. 

    server-spec is a map with any of the following keys: 
    :host  (\"127.0.0.1\") 
    :port  (6379) 
    :db  (0) 
    :timeout (5000) 
    :password (nil)" 
    ([server-spec & body] 
    `(with-connection connection# *pool* ~server-spec 
     (binding [redis.vars/*channel* (make-direct-channel connection#)] 
      [email protected])))) 

original code in context here

我似乎沒有能夠重新定義宏在我的測試代碼和功能包宏沒有按因爲我仍然需要身體被執行來產生我的結果,所以我不會再向前走。我最想做的是執行傳遞給連接宏的主體,並丟棄宏的其餘部分。有任何想法嗎?

+0

經過這個問題,我發現https:// github。com/ptaoussanis/carmine/issues/16,然後決定對我的單元測試命中本地redis實例是完全正確的 –

回答

1

我建議你問的問題Midje mailing list(然後,當然,在這裏張貼最終的答案)。不知道你想要測試什麼,很難提供建議。也許(以下是Freeman和Pryce的Growing Object-Oriented Software(這確實適用於Clojure--事實上,支持這種風格是我寫Midje的原因)),您想要將問題分爲兩部分。首先,您要構建一組隔離Redis的函數。您可以測試這些函數是否可以正常運行,並且與真正的數據庫一起工作的緩慢而繁瑣的直接測試。

這些函數會隱藏連接和包裝宏的需要。

然後,您可以使用Midje先決條件測試您的代碼是否正確調用隔離功能。

Avdi Grimm's Objects on Rails是另一本關於隔離數據庫的文章。

注意:我對Redis一無所知,但其他一些Clojure->數據庫庫免去了智力上的包裝宏(with-server)。相反,他們進入有狀態路由並擁有一個保存連接的全局變量,就像(比方說)Ruby數據庫庫ActiveRecord(隱式地)和Sequel(顯式)那樣。儘管不那麼純粹,但似乎使生活(包括測試)更簡單。在Midje,這種聯繫可以用一個metaconstant來表示。

2

我經常編寫用於測試的綁定包裝宏。這些宏只是將其他的東西綁定到無法測試的函數或宏。在這種情況下,我會寫沿着這些線路

(defmacro my-fake-with-server [] 
    ....) 

(defmacro with-fake-with-server 
     (binding [redis.core/with-server my-fake-with-server] 
       (insert test here))) 

(deftest my-test (with-fake-with-server (function-that-uses-with-server))) 

這樣可以使所有的嘲諷在測試代碼的東西。

+0

我似乎無法做到這一點,我得到錯誤「Can not dynamic bind non -dynamic var:redis.core/with-server「 – jamiei

+0

好主意。像這樣的東西適合midje。 @jamiei來避免這個問題,在你自己的命名空間中引入另一個間接尋址,聲明它是動態的,並且在你的測試中用綁定模擬_that_ –