9

How can I wrap a string in an input-stream in such a way that I can test the function bellow?

(defn parse-body [body]
    (cheshire/parse-stream  (clojure.java.io/reader body) true))

(deftest test-parse-body
    (testing "read body"
        (let [body "{\"age\": 28}"]  ;; must wrap string
            (is (= (parse-body body) {:age 28}))
            )))
1
  • 4
    The accepted answer is good and answers your title question, but know that clojure.java.io/reader accepts any (char-based) java.io.Reader, and so the detour to (byte-based) java.io.InputStream and character encoding is unnecessary. Instead, simply wrap the string in a java.io.StringReader: (java.io.StringReader. body). Commented Jul 9, 2016 at 21:18

1 Answer 1

15

It is straightforward to construct an InputStream from a String using host interop, by converting to a byte-array first:

(defn string->stream
  ([s] (string->stream s "UTF-8"))
  ([s encoding]
   (-> s
       (.getBytes encoding)
       (java.io.ByteArrayInputStream.))))

As another stream and byte interop example, here's a function that returns a vector of the bytes produced when encoding a String to a given format:

(defn show-bytes
  [s encoding]
  (let [buf (java.io.ByteArrayOutputStream.)
        stream (string->stream s encoding)
        ;; worst case, 8 bytes per char?
        data (byte-array (* (count s) 8))
        size (.read stream data 0 (count data))]
    (.write buf data 0 size)
    (.flush buf)
    (apply vector-of :byte (.toByteArray buf))))

+user=> (string->stream "hello")
#object[java.io.ByteArrayInputStream 0x39b43d60 "java.io.ByteArrayInputStream@39b43d60"]
+user=> (isa? (class *1) java.io.InputStream)
true
+user=> (show-bytes "hello" "UTF-8")
[104 101 108 108 111]
+user=> (show-bytes "hello" "UTF-32")
[0 0 0 104 0 0 0 101 0 0 0 108 0 0 0 108 0 0 0 111]
Sign up to request clarification or add additional context in comments.

1 Comment

Works as a charm! Many thanks for your help. Perfect answer!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.