2017-03-01 29 views
1

我想知道在Clojure集成测试(Ruby的webmock)中是否有广泛使用的模式或解决方案将出站HTTP请求存储到第三方。我希望能够在高级别存根请求(例如,在一个设置函数中),而不必将我的每个测试都包含在(with-fake-http [] ...)之类的东西中,或者不得不依赖于依赖注入。在Clojure测试中存储HTTP请求的策略

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

交换包含假函数的测试专用ns是否合理?有没有一种干净的方式在我的测试中做到这一点?

+1

大多数(所有?)clojure http库都将请求和响应表示为映射,因此您可以直接在测试中构建这些请求而不会嘲笑。 – Lee

+0

依赖注入有什么问题?你是否在自己的职位上使用硬编码的网址?因为你不应该这样做,那很糟糕,mkay。 –

回答

1

我曾经有过类似的情况,但是我找不到任何满足我需求的Clojure库,所以我创建了自己的库,名为Stub HTTP。用法示例:

(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)))))) 
+1

谢谢你。我会调查你的图书馆并跟进。 :) – pdoherty926

0

可以使用环/的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调用,您可能会发现with-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

完整文档is at ClojureDocs

+0

谢谢你。我已经更新了我的问题,以更具体地说明我要存根据的请求类型。特别是,我的应用程序向第三方发出的出站请求。 – pdoherty926

+0

再次感谢。我会试验你的建议和后续行动(可能会有几天)。乍一看,与webmock这样的解决方案相比,这是相当笨拙的,因为我需要深入了解嵌套函数调用将会做什么。 – pdoherty926