如何在 Midje 中定义先决条件函数?
How to define prerequisite functions in Midje?
首先我应该说我是 Clojure 的新手,一般来说是 FP。我一直在阅读有关如何在 Midje 中定义先决条件的文档,但我无法理解其中的一些内容。
我的理解是,要进行自上而下的 TDD,您应该首先在测试模块中编写一个测试,并在顶部添加一个 unfinished
语句,'declares' 所有您尚未定义的先决条件功能。然后,您可以 fiddle 在测试中 provided
函数中使用那些先决条件函数(描述它们的 return 值等)。
我的困惑在于你应该如何让你的实际源模块识别先决条件函数。这是一个非常简单和人为的例子,我将用它来说明我的意思:
;;; 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
[])
到目前为止一切顺利。我 运行 测试失败,因为:
a) do-turns
没有被调用
b) start-game
没有 return 任何东西。
所以现在要使测试通过,将 start-game
更改为 call 和 return (do-turns)
。作为记录,do-turns
是一个假设的先决条件函数,我将从一个尚不存在的模块中获得——据我所知,这就是自上而下的 TDD 的工作方式。
(defn start-game
[]
(do-turns))
现在,可以理解,我得到了一个巨大的错误; Clojure 无法解析符号 do-turns
。所以我想,也许如果我 (declare do-turns)
在顶部,我可以防止它爆炸。不,我得到了一个不同的错误,因为我试图调用一个未绑定的函数。
我尝试了其他几种让 Clojure 识别 do-turns
的方法,但似乎 unfinished
语句给它带来了问题。我只是使用 unfinished
错了吗?
来自Midje docs:
unfinished
is similar to Clojure's declare
in that it can take multiple arguments and define a var for each one of them. Unlike declare, it binds the var to a function that blows up if called
所以当你做 (unfinished do-turns)
然后用 (do-turns)
调用它时抛出异常:
Error #'do-turns
[the var] has no implementation, but it was called like this:
(do-turns)
midje.util.exceptions/user-error (exceptions.clj:13)
您可以通过删除 (unfinished do-turns)
部分并提供 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)
returns 的调用 (do-turns
) returns.
首先我应该说我是 Clojure 的新手,一般来说是 FP。我一直在阅读有关如何在 Midje 中定义先决条件的文档,但我无法理解其中的一些内容。
我的理解是,要进行自上而下的 TDD,您应该首先在测试模块中编写一个测试,并在顶部添加一个 unfinished
语句,'declares' 所有您尚未定义的先决条件功能。然后,您可以 fiddle 在测试中 provided
函数中使用那些先决条件函数(描述它们的 return 值等)。
我的困惑在于你应该如何让你的实际源模块识别先决条件函数。这是一个非常简单和人为的例子,我将用它来说明我的意思:
;;; 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
[])
到目前为止一切顺利。我 运行 测试失败,因为:
a) do-turns
没有被调用
b) start-game
没有 return 任何东西。
所以现在要使测试通过,将 start-game
更改为 call 和 return (do-turns)
。作为记录,do-turns
是一个假设的先决条件函数,我将从一个尚不存在的模块中获得——据我所知,这就是自上而下的 TDD 的工作方式。
(defn start-game
[]
(do-turns))
现在,可以理解,我得到了一个巨大的错误; Clojure 无法解析符号 do-turns
。所以我想,也许如果我 (declare do-turns)
在顶部,我可以防止它爆炸。不,我得到了一个不同的错误,因为我试图调用一个未绑定的函数。
我尝试了其他几种让 Clojure 识别 do-turns
的方法,但似乎 unfinished
语句给它带来了问题。我只是使用 unfinished
错了吗?
来自Midje docs:
unfinished
is similar to Clojure'sdeclare
in that it can take multiple arguments and define a var for each one of them. Unlike declare, it binds the var to a function that blows up if called
所以当你做 (unfinished do-turns)
然后用 (do-turns)
调用它时抛出异常:
Error
#'do-turns
[the var] has no implementation, but it was called like this:(do-turns)
midje.util.exceptions/user-error (exceptions.clj:13)
您可以通过删除 (unfinished do-turns)
部分并提供 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)
returns 的调用 (do-turns
) returns.