2017-09-15 18 views
2

나는 Clojure와 FP에 일반적이지 않다는 말로 시작해야한다. Midje에서 전제 조건을 정의하는 방법에 대한 설명서를 읽었지 만 일부 내용을 이해할 수는 없습니다.Midje에서 전제 조건 함수를 정의하는 방법은 무엇입니까?

내 이해는 하향식 TDD를 수행하는 것이고, 정의하지 않은 모든 필수 기능을 '선언'하는 상단에 unfinished 문을 사용하여 테스트 모듈에 테스트를 작성해야한다는 것을 이해했습니다. 아직. 그런 다음 테스트 내에서 provided 함수의 해당 필수 기능 (반환 값 등을 설명)을 활용할 수 있습니다.

내 혼란은 실제 소스 모듈에서 사전 준비 기능을 인식하는 방법에 있습니다. 난 그냥 내 run_game 모듈에 함수의 스텁을 작성

;;; 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..)) 

그리고 테스트가 제대로 실패 할 : 여기 내 의미를 설명하는 데 사용할 매우 간단하고 인위적인 예입니다.

(ns clojure-ttt.run-game) 

    (defn start-game 
     []) 

지금까지 그렇게 좋았습니다. 테스트를 실행하면 다음과 같은 이유로 실패합니다.
a) do-turns이 호출되지 않습니다.
b) start-game이 반환하지 않습니다.

그래서 이제는 start-game을 변경하고 (do-turns)을 호출하여 테스트를 통과하십시오. 기록을 위해 do-turns은 내가 아직 이해하지 못했던 기존 모듈에서 얻으려는 가상의 전제 조건 기능입니다.

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

자, 당연히, 나는 큰 오류가 있습니다. Clojure는 기호 do-turns을 해석 할 수 없습니다. 그래서 나는 어쩌면 내가 (declare do-turns) 상단에서 나는 그것을 부 풀릴 수 있다고 생각했다. 아니, 언 바운드 함수를 호출하려고하기 때문에 다른 오류가 발생합니다.

나는 Clojure를 do-turns으로 인식하는 몇 가지 다른 방법을 시도했지만 unfinished 문이 문제를 일으키는 것처럼 보입니다. 내가 방금 unfinished을 잘못 사용하고 있습니까? Midje docs에서

답변

1

:

unfinished는 Clojure에서의 declare는 여러 인자를하고 각 하나에 대한 VAR을 정의 할 수 있다는 점에서 유사하다.

오류 #'do-turns [var에]이 있습니다 선언과는 달리, 당신이 (unfinished do-turns)을 다음 예외가 발생합니다 (do-turns)로를 호출 할 때 그래서

라고하면 불면 함수에 VAR를 결합 더 구현하지만,이 같은 호출되지되었습니다 (do-turns) midje.util.exceptions/사용자 오류 (exceptions.clj : 13)

당신은 (unfinished do-turns) 파를 제거하여이 문제를 해결할 수 있습니다 그리고 do-turns의 구현을 제공합니다. 예 :,

(ns clojure-ttt.run-game) 

(defn do-turns) 
    []) 

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

하고 do-turns의 구현을 제공 한 경우 구현이 이미 존재하기 때문에, (unfinished 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 

참고를 참조, 그래서 제거됩니다.

(start-game)을 호출하면 (do-turns이 반환하는 것으로 나타났습니다.

+1

감사합니다. 작동합니다. 나의 유일한 관심사는'do-turns'를 다른 네임 스페이스에 넣으면'start-game'이있는 네임 스페이스와 do-turns가있는 네임 스페이스를 모두 내 테스트 모듈로 가져와야한다는 것입니다 '살아 있니? OOP에서 필자는 테스트중인 클래스를 해당 테스트 디렉토리로 가져 오기만하고 종속성을 조롱합니다. 그 패턴은 Clojure에서 가능하지 않습니까? –

+1

예.'do-turns'와'start-game'이 다른 네임 스페이스에있는 경우 두 네임 스페이스 모두를 가져 오거나'clojure-ttt.other-namespace/do-turns'와 같은 완전한 이름을 부여해야합니다. '제공됨 '은 ['with-redefs'] (https://clojuredocs.org/clojure.core/with-redefs)를 사용하고이를 덮어 쓰려면 var에 액세스해야합니다. 추상화에 의존하려면 프로토콜을 사용할 수 있습니다. –