Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure单元测试中DEFTEST之间传递变量_Clojure - Fatal编程技术网

Clojure单元测试中DEFTEST之间传递变量

Clojure单元测试中DEFTEST之间传递变量,clojure,Clojure,我试图编写一些单元测试,测试一些db模型 我想让我的第一个deftest函数获取插入用户的db生成ID,将其保存在某个地方,以便下一个deftest可以从db中获取相同的用户 我想我可以通过在第一个deftest中使用def来实现这一点,但是在第二个deftest中,定义的var被认为是未绑定的var。这是我的密码: (deftest test-user->db (testing "Adding a new user record to db" (->> (user

我试图编写一些单元测试,测试一些db模型

我想让我的第一个deftest函数获取插入用户的db生成ID,将其保存在某个地方,以便下一个deftest可以从db中获取相同的用户

我想我可以通过在第一个deftest中使用
def
来实现这一点,但是在第二个deftest中,定义的var被认为是未绑定的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
top-level来解决这个问题,然后在两个测试中使用它,这样测试顺序就不重要了。如果您不希望在绝对需要之前对其进行初始化,则可以将其包装为
延迟

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

我想补充一下@carcigenicate上面的答案,以防其他人无意中发现这个主题,并希望按顺序运行某些测试函数(因为默认情况下,它们不会按顺序运行)

在特定测试的N中,创建一个名为
test ns hook
的函数,并按照您希望它们运行的顺序调用测试函数。如果在ns中定义了test ns hook,那么测试运行程序将只运行该函数,而不是在该ns中定义的所有测试

所以在我的问题中,我在文件末尾添加了这个函数:

(defn test-ns-hook []
  (test-user->db)
  (test-db->user))

这确保首先运行并完成
test user->db
,绑定变量,然后运行绑定该变量的
test db->user

@cyehia Ya,np。请注意,
延迟
可能不是必需的。但是,如果
user->db
很昂贵,您可能会发现将调用延迟到测试运行而不是文件运行时调用它是一件好事。