how do i mock a json post request in ring?

醉酒当歌 提交于 2019-12-08 19:23:09

问题


I'm using peridot - https://github.com/xeqi/peridot to test my ring application, and its working fine until I try to mock a post request with json data:

(require '[cheshire.core :as json])
(use 'compojure.core)

(defn json-post [req]
  (if (:body req)
    (json/parse-string (slurp (:body req)))))

(defroutes all-routes
  (POST "/test/json" req  (json-response (json-post req))))

(def app (compojure.handler/site all-routes))

(use 'peridot.core)

(-> (session app)
    (request "/test/json"
             :request-method :post
             :body (java.io.ByteArrayInputStream. (.getBytes "hello" "UTF-8")))

gives IOException: stream closed.

Is there a better way to do this?


回答1:


tldr:

(-> (session app)
    (request "/test/json"
             :request-method :post
             :content-type "application/json"
             :body (.getBytes "\"hello\"" "UTF-8")))

When peridot generates a request map it will default to application/x-www-form-urlencoded for the content-type for a :post request. With the app as specified wrap-params (which is included by compojure.handler/site) will attempt to read the :body in order to parse any form-urlencoded parameters. Then json-post attempts to read the :body again. However InputStreams are designed to be read once, and that causes the exception.

There are basically two ways to solve the issue:

  1. Remove compojure.handler/site.
  2. Add a content type to the request (as done in the tldr)



回答2:


(require '[cheshire.core :as json])

(-> (session app)
    (request "/test/json"
             :request-method :post
             :content-type "application/json"
             :body (json/generate-string data))

No need to call .getBytes, just pass json with :body parameter.



来源:https://stackoverflow.com/questions/17035319/how-do-i-mock-a-json-post-request-in-ring

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!