clojure - 在 Clojure 单元测试中的 deftests 之间传递变量
问题描述
我正在尝试编写一些单元测试,以测试一些数据库模型。
我希望我的第一个 deftest 函数获取插入用户的 db 生成的 ID,将其保存在某处,以便下一个 deftest 可以从 db 中获取同一用户。
我想我可以通过def
在第一个 deftest 中使用来做到这一点,但是定义的 var 在第二个 deftest 中被认为是 Unbound Var。这是我的代码:
(deftest test-user->db
(testing "Adding a new user record to db"
(->> (user->db {:name "Bob"}) ;; returns a UUID ID
(def mock-user-id)) ;; binding it here
(is (uuid? mock-user-id)))) ;; this passes
(deftest test-db->user
(testing "Getting a user record from db"
(let [user (db->user mock-user-id)] ;; mock-user-id is unbound :-/
(is (instance? User user))
(is (contains? user :id))
(is (contains? user :name))
(is (= mock-user-id (:id user)))
(is (= "Bob" (:name user))))))
不幸的是,我找不到任何关于为什么会这样的资源。我只能假设命名空间的全局变量以某种方式为每个 deftest 重置?
解决方案
显然测试不一定按顺序运行:
(deftest a-test
(println "a")
(def inner "hello"))
(deftest b-test
(println "b")
(println "inner" inner))
Testing tic-tac-toe.core-test
b
inner #object[clojure.lang.Var$Unbound 0x37acbc9e Unbound: #'tic-tac-toe.core-test/inner]
a
Ran 2 tests containing 0 assertions.
0 failures, 0 errors.
=> {:test 2, :pass 0, :fail 0, :error 0, :type :summary}
请注意如何首先打印“b”。这意味着您的 var 在需要时可能尚未初始化。
我会通过声明mock-user-id
顶级来解决这个问题,然后在两个测试中使用它,这样测试顺序就无关紧要了。delay
如果您不希望在绝对需要之前对其进行初始化,则可以将其包装在 a 中:
; delay will delay initialization until it's first used
(def mock-user-id (delay (user->db {:name "Bob"})))
(deftest test-user->db
(testing "Adding a new user record to db"
(is (uuid? @mock-user-id)))) ; @ to force the delay to run its body the first time
(deftest test-db->user
(testing "Getting a user record from db"
(let [user (db->user @mock-user-id)] ;; mock-user-id is unbound :-/
(is (instance? User user))
(is (contains? user :id))
(is (contains? user :name))
(is (= @mock-user-id (:id user)))
(is (= "Bob" (:name user))))))
推荐阅读
- javascript - 从浏览器网页检测应用程序是否安装在桌面上
- d3.js - 任何 js 库中带有 4 个标签(对面图)的散点图?
- html - 带有搜索栏的 EJS 表单 GET 请求未按预期工作
- r - 仅产生一组的 ntile 函数
- javascript - 当用户单击 Mozilla Firefox 的后退按钮时如何避免多个更改框
- google-apps-script - 如何将数组发送到 Google 表格范围?
- java - 删除 jar 文件时优雅地关闭 jvm
- azure - 复制 Azure Application Insights 仪表板并指向新的 Application Insights 实例
- rspec - 测试是否在控制器中调用了来自另一个范围的方法
- python-3.x - pandas:重新采样和计算正确的平均值