如何在Clojure中进行集成测试?

5

在Clojure中进行集成测试的技术和库有哪些?具体包括与数据库、ring应用程序、core.async通道以及产生副作用的任何内容的交互。

1个回答

7

您可以使用ring-mock来进行Ring应用程序的模拟。以下是创建模拟处理程序并使用它的示例:

(let [h (-> (POST "/some/url" [] some-resource)
            (wrap-defaults api-defaults))]
  (let [resp (h (-> (request :post "/some/url")
                    (header "content-type" "application/json")
                    (body (generate-string {:foo :bar}))))]
    (is (= 303 (:status resp)))
    (is (= "" (:body resp)))
    (is (= "http://some/place/foo" (get-in resp [:headers "Location"])))))

对于d/b交互测试和副作用,我使用with-redefs来替换实际的副作用函数,并捕获和测试其预期参数。我不确定这是否符合惯例,但这是我发现最容易的方法,例如:

(testing "some d/b work"
  (let [insert-data (ref {})]
    (with-redefs
      [d/insert-data<! 
       (fn [db data] (dosync (alter insert-data assoc :db db)
                             (alter insert-data assoc :data data)))]
      (let [d (your-fn your-args)]
        (is (= {:some :expected-result} d))
        (is (= {:db {:some :connection-data} :data {:some :expected-data}} @insert-data))))))

当您需要在测试一些涉及写回的代理时,历史上我必须使用refs,而这种情况下atoms不能工作。

我主要使用的库是clojure.test,至今只是简单尝试了一下test.check 进行属性测试。我曾经使用Midje很长一段时间,但后来发现clojure.test更加纯粹,但那只是个人喜好。此外,如果你开始进入cljs,请坚持使用一个测试框架。

我没有使用core.async的经验,但它自己的测试看起来是个好的起点。


2
这个答案更适合单元测试。集成测试的设置高度取决于具体情况。 - Ming

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接