2017-09-15 96 views
2

我應該說我是新來的Clojure開始,FP一般。我一直在閱讀有關如何在Midje定義先決條件的文件,但我不能做一些它的意義。如何定義Midje的先決條件?

我的理解是要做自上而下的TDD,你應該首先在你的測試模塊中寫一個測試,在上面聲明一個unfinished聲明'聲明'你沒有定義的所有先決條件函數然而。然後你就可以在你的測試中provided功能的前提功能(描述他們的返回值,這樣)撥弄。

我的困惑就在於你應該如何讓你的實際源模塊識別的前提功能。這裏有一個非常簡單的和人爲的例子,我會用它來說明我的意思:

;;; in my run_game_test module 

    (ns clojure-ttt.run-game-test 
     (:require [midje.sweet :refer :all] 
       [clojure-ttt.run-game :refer [start-game]])) 

    (unfinished do-turns) 

    (fact "`start-game` returns whatever `do-turns` returns" 
     (start-game) => ..winner.. 
     (provided 
     (do-turns) => ..winner..)) 

然後使試驗失敗正確,我只是寫一個函數的存根在我run_game模塊。

(ns clojure-ttt.run-game) 

    (defn start-game 
     []) 

到目前爲止好。我進行的測試,他們失敗的原因:
一)do-turns是沒有得到所謂的
B)start-game不返回任何東西。

所以現在讓測試通過,通過改變start-game調用和返回(do-turns)。爲了記錄,do-turns是一個假設的先決條件函數,我將從一個尚不存在的模塊中獲取 - 據我所知,它是自頂向下TDD的工作原理。

(defn start-game 
     [] 
     (do-turns)) 

現在,可以理解的是,我得到了一個巨大的錯誤; Clojure無法解析符號do-turns。所以我想,也許如果我(declare do-turns)在上面,我可以把它炸燬。不,我得到一個不同的錯誤,因爲我試圖調用一個未綁定的函數。

我嘗試了幾種讓Clojure識別do-turns的方法,但似乎unfinished聲明給它提出了問題。我剛剛使用unfinished錯了嗎?

回答

1

Midje docs

unfinished類似於Clojure的declare,它可以採取多個參數,並定義它們中的每一個變種。不同於聲明,它結合了var來好象叫

所以當你做(unfinished do-turns),然後用(do-turns)調用它拋出一個異常,吹拂了一個功能:

錯誤#'do-turns [使用var]有沒有實現,但它被稱爲是這樣的: (do-turns) midje.util.exceptions /用戶錯誤(exceptions.clj:13)

您可以通過刪除(unfinished do-turns) PA解決這個問題rt並提供do-turns的實施。例如。,

(ns clojure-ttt.run-game) 

(defn do-turns) 
    []) 

(defn start-game 
    [] 
    (do-turns)) 

,並指它在測試

(ns clojure-ttt.run-game-test 
    (:require [midje.sweet :refer :all] 
      [clojure-ttt.run-game :refer [start-game do-turns]])) ; <- do-turns 

;; Remove `(unfinished do-turns)` since it is no longer unfinished 

(fact "`start-game` returns whatever `do-turns` returns" 
    (start-game) => ..winner.. 
    (provided 
    (do-turns) => ..winner..)) 
;; => returns true 

注意,當您所提供的do-turns的實現,(unfinished do-turns)會因爲實現已經存在拋出異常,因此它被刪除。

現在您已經顯示致電(start-game)返回(do-turns)返回的內容。

+1

謝謝,這是有效的。我唯一擔心的是,如果我將'do-turns'放入不同的命名空間,這是否意味着我將不得不將導入到我的測試模塊中的'start-game'所在的命名空間和'do-turns'命名空間「生活?在OOP中,我只着重於將被測試的類導入相應的測試目錄,並嘲笑依賴關係。這種模式在Clojure中是不可能的嗎? –

+1

是的,如果'do-turns'和'start-game'在不同的命名空間中,則需要導入這兩個命名空間或給出完全限定的名稱,如'clojure-ttt.other-namespace/do-turns'。 'provided'使用['with-redefs'](https://clojuredocs.org/clojure.core/with-redefs),你需要訪問var來覆蓋它。如果你想依賴抽象,你可以使用協議。 –

相關問題