2013-06-11 2 views
8

Я использую перидот - https://github.com/xeqi/peridot, чтобы проверить мое кольцо приложения, и его работает отлично, пока я пытаюсь издеваться пост запрос с данными JSON:Как я могу высмеять запрос json post в кольце?

 
(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"))) 

дает IOException: stream closed.

Есть ли лучший способ сделать это?

ответ

9

tldr:

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

Когда перидот генерирует карту запроса по умолчанию будет application/x-www-form-urlencoded для типа контента для :post запроса. В приложении, указанном wrap-params (который включен compojure.handler/site), будет предпринята попытка прочитать :body для анализа любых параметров, заданных с помощью формы. Затем json-post снова пытается прочитать :body. Однако InputStream s предназначены для чтения один раз, и это вызывает исключение.

Есть два основных способа решения проблемы:

  1. Удалить compojure.handler/site.
  2. Добавить тип содержимого для запроса (как это было сделано в tldr)
4
(require '[cheshire.core :as json]) 

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

Нет необходимости называть .getBytes, просто передать JSON с :body параметром.

Смежные вопросы