2013-06-11 12 views
8

Używam oliwin - https://github.com/xeqi/peridot przetestować aplikację ring i jej działa dobrze, dopóki próbuję mock żądania POST z danych json:Jak wykpić żądanie json po dzwonku?

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

daje IOException: stream closed.

Czy jest lepszy sposób to zrobić?

Odpowiedz

9

tldr:

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

Kiedy oliwin generuje mapę żądania domyślnym będzie application/x-www-form-urlencoded dla typu zawartości dla żądania :post. Dzięki aplikacji określonej jako wrap-params (która jest dołączona przez compojure.handler/site) spróbuje odczytać :body, aby przeanalizować dowolne parametry w postaci urlcode. Następnie json-post ponownie próbuje odczytać :body. Jednak InputStream s są przeznaczone do odczytu raz, a to powoduje wyjątek.

Istnieją dwa sposoby rozwiązania tego problemu:

  1. Usuń compojure.handler/site.
  2. Dodaj typ zawartości na żądanie (jak to zrobiono w tldr)
4
(require '[cheshire.core :as json]) 

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

ma potrzeby skorzystania .getBytes, po prostu przekazać json z :body parametru.

Powiązane problemy