Clojure测试中的HTTP请求存根策略

Clojure测试中的HTTP请求存根策略,clojure,mocking,stubbing,Clojure,Mocking,Stubbing,我想知道是否有一种广泛使用的模式或解决方案,用于在Clojure集成测试(一种la Ruby)中将出站HTTP请求存根到第三方。我希望能够在高层(例如,在设置函数中)存根请求,而不必将我的每个测试包装在类似(使用伪http[…])的东西中,也不必求助于依赖项注入 这是动态var的一个很好的用例吗?我想我可以在设置步骤中进入有问题的名称空间,并将副作用函数设置为无害的匿名函数。然而,这让我感觉很沉重,我不喜欢为了适应我的测试而修改我的应用程序代码。(这也不比上面提到的解决方案好多少。) 在包含伪函

我想知道是否有一种广泛使用的模式或解决方案,用于在Clojure集成测试(一种la Ruby)中将出站HTTP请求存根到第三方。我希望能够在高层(例如,在设置函数中)存根请求,而不必将我的每个测试包装在类似
(使用伪http[…])
的东西中,也不必求助于依赖项注入

这是动态var的一个很好的用例吗?我想我可以在设置步骤中进入有问题的名称空间,并将副作用函数设置为无害的匿名函数。然而,这让我感觉很沉重,我不喜欢为了适应我的测试而修改我的应用程序代码。(这也不比上面提到的解决方案好多少。)


在包含伪函数的测试特定ns中交换是否有意义?在我的测试中是否有一种干净的方法可以做到这一点?

您可以看到一个使用ring/compojure框架的好例子:

> lein new compojure sample
> cat  sample/test/sample/handler_test.clj


(ns sample.handler-test
  (:require [clojure.test :refer :all]
            [ring.mock.request :as mock]
            [sample.handler :refer :all]))

(deftest test-app
  (testing "main route"
    (let [response (app (mock/request :get "/"))]
      (is (= (:status response) 200))
      (is (= (:body response) "Hello World"))))

  (testing "not-found route"
    (let [response (app (mock/request :get "/invalid"))]
      (is (= (:status response) 404)))))
更新 对于出站http调用,您可能会发现使用redefs的
很有用:

(ns http)

(defn post [url]
  {:body "Hello world"})

(ns app
  (:require [clojure.test :refer [deftest is run-tests]]))

(deftest is-a-macro
  (with-redefs [http/post (fn [url] {:body "Goodbye world"})]
    (is (= {:body "Goodbye world"} (http/post "http://service.com/greet")))))

(run-tests) ;; test is passing
在本例中,原始函数
post
返回“Hello world”。在单元测试中,我们使用返回“再见世界”的存根函数临时重写
post


完整的文档。

不久前我也遇到过类似的情况,我找不到任何满足我需要的Clojure库,所以我创建了自己的库,名为。用法示例:

(ns stub-http.example1
  (:require [clojure.test :refer :all]
            [stub-http.core :refer :all]
            [cheshire.core :as json]
            [clj-http.lite.client :as client]))

(deftest Example1  
    (with-routes!
      {"/something" {:status 200 :content-type "application/json"
                     :body   (json/generate-string {:hello "world"})}}
      (let [response (client/get (str uri "/something"))
            json-response (json/parse-string (:body response) true)]
        (is (= "world" (:hello json-response))))))

大多数(全部?)clojure http库将请求和响应表示为映射,因此您可以直接在测试中构造它们,而无需模拟?您是否在函数中硬编码URL?因为你不应该那样做,那很糟糕,mkay。谢谢你。我已经更新了我的问题,以便更具体地说明我正在尝试存根的请求类型。特别是,我的应用程序向第三方发出的出站请求。再次感谢。我将尝试你的建议并跟进(可能需要几天时间)。乍一看,与webmock这样的解决方案相比,这是相当麻烦的,因为我需要深入了解嵌套函数调用将要执行的操作。谢谢。我将调查您的图书馆并跟进。:)有没有办法匹配路线中的
/something/