我正在尝试为我的clojure函数编写一些单元测试(我正在使用clojure.test,但如果需要我可以切换到midje).
我有一个函数,如下所示:
(defn GenerateNodes
[is-sky-blue? hot-outside? name]
(cond
(is-sky-blue? name) (generate-sky-nodes)
(hot-outside?) (generate-hot-nodes)))
Run Code Online (Sandbox Code Playgroud)
单元测试此函数时,我想编写以下测试用例:
(deftest when-sky-blue-then-generate-sky-nodes
(let [is-sky-blue true]
(GenerateNodes (fn[x] println "sky nodes generated."))
(is (= true Was-generate-hot-nodes-called?))
Run Code Online (Sandbox Code Playgroud)
如何断言函数generate-sky-nodes被调用?或不 ?我会在C#或java中使用一个模拟框架,但我不知道clojure.
我正在阅读关于TDD的Clojure on Action第8章,并尝试使用stubing宏.它使用动态绑定机制来存根函数.唉,在Clojure 1.3中,不可能将绑定机制用于非动态变量,因此在大多数情况下,存根宏不起作用,除非您明确声明指向函数动态的var.然后我想知道在Midje如何进行存根并试图找到"提供"的来源,但我找不到它.所以这里:
如何在Midje实施"提供"?有人可以详细解释一下吗?
这是情况:我正在尝试单元测试函数A调用函数B.函数B在弹弓try +块中调用,在某些情况下它可以使用弹弓投掷+.我想在midje测试中模拟函数B,以便返回try + block中的catch实际捕获的内容.我似乎无法创造出正确的东西.这是代码和测试的大致缩略图:
(defn function-A
[param]
(try+
(function-B param)
(catch [:type :user-not-found]
(do-something))))
(defn function-B
[param]
(throw+ [:type :user-not-found]))
(fact "do-something is called"
(function-A "param") => (whatever is the result of calling do-something)
(provided
(function-B "param") =throws=> (clojure.lang.ExceptionInfo. "throw+: {:type :user-not-found}"
{:object {:type :user-not-found}, :environment {}}
nil)))
Run Code Online (Sandbox Code Playgroud)
我正在抛出的ExceptionInfo似乎是正确的.当我的应用程序通过大量的prn语句运行时,我可以看到这一点.但是,无论我尝试什么,我都无法让测试工作.
我还在repl中尝试了下面的代码,看看我是否能理解这个问题.然而,虽然两段代码似乎都涉及相同的异常,但只有一个(纯粹的弹弓)设法捕获并打印"抓住它".我想如果我能理解为什么一个有效而另一个无法有效,我就可以通过单元测试解决问题.
(try+
(try
(throw+ {:type :user-not-found})
(catch Exception e
(prn "Caught: " e)
(prn "Class: " (.getClass e))
(prn "Message: " (.getMessage e))
(prn "Cause: " (.getCause e))
(prn "Data: " …Run Code Online (Sandbox Code Playgroud) 考虑下面的(最小)leiningen项目
./project.clj:
(defproject repro "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.5.1"]
[midje "1.5.1"]])
Run Code Online (Sandbox Code Playgroud)
./repro/src/repro/core.clj:
(ns repro.core)
Run Code Online (Sandbox Code Playgroud)
./repro/test/repro/core_test.clj:
(ns repro.core-test
(:require [repro.core :refer :all]
[midje.sweet :refer :all]))
(facts "about numbers"
(fact "trivial"
1 => 1) )
Run Code Online (Sandbox Code Playgroud)
如果我安装了leiningen midje插件,它将在命令提示符下运行,如下所示:
lein clean
lein midje
~~> All checks (1) succeeded.
Run Code Online (Sandbox Code Playgroud)
但是,如果将leiningen项目导入Intellij 12.1.5 Community Edition,则会出现大量堆栈跟踪:
Exception in thread "main" java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
...
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.NullPointerException
at java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:333)
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:988)
at clojure.lang.Namespace.find(Namespace.java:188)
at clojure.core$find_ns.invoke(core.clj:3728)
at clojure.core$the_ns.invoke(core.clj:3760)
at clojure.core$ns_name.invoke(core.clj:3767)
at midje.Bootstrap$bootstrap.invoke(Bootstrap.clj:8)
at …Run Code Online (Sandbox Code Playgroud) 当我使用外部 let 子句来构建一些定义和调用进行测试时,存根不会按我预期的方式工作。例如:
本次测试失败
(fact "blah"
(let [x (meth1 123)]
x => 246
(provided
(meth2 123) => 246)))
Run Code Online (Sandbox Code Playgroud)
有了这个代码
(defn meth2 [x]
(prn "meth2" x)
(* 3 x))
(defn meth1 [x]
(let [y (meth2 x)]
y))
Run Code Online (Sandbox Code Playgroud)
我不应该使用letmidje 语句吗?我不明白如何在不删除let.
我尝试lein new compojure financeiro使用 midje 框架在 leiningen 的 compojure 模板 ( ) 中运行测试并收到警告:
lein midje
WARNING: any? already refers to: #'clojure.core/any? in namespace: leiningen.midje, being replaced by: #'leiningen.midje/any?
nil
All checks (3) succeeded.
Run Code Online (Sandbox Code Playgroud)
我的测试代码handler_test.clj:
lein midje
WARNING: any? already refers to: #'clojure.core/any? in namespace: leiningen.midje, being replaced by: #'leiningen.midje/any?
nil
All checks (3) succeeded.
Run Code Online (Sandbox Code Playgroud)
我的项目文件project.clj:
(ns financeiro.handler-test
(:require
; [clojure.test :refer :all]
[midje.sweet :refer :all]
[ring.mock.request :as mock]
[financeiro.handler :refer :all]))
; (deftest test-app …Run Code Online (Sandbox Code Playgroud) clojure ×6
midje ×6
leiningen ×2
mocking ×2
tdd ×2
unit-testing ×2
compojure ×1
la-clojure ×1
stubbing ×1