Skip to content

Add example of mocking using with-redefs #57

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ aws.clj
/.lein-deps-sum
.cache
.cpcache
.idea
*.iml
60 changes: 56 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,63 @@ A proxy can be specified by setting the Java properties:
`<scheme>.proxyHost` and `<scheme>.proxyPort` where `<scheme>` is the client
scheme used (normally 'http' or 'https').

## Faking clj-http responses
## Mocking clj-http responses

If you need to fake clj-http responses (for things like testing and
such), check out the
[clj-http-fake](https://github.com/myfreeweb/clj-http-fake) library.
Mocking responses from the clj-http-lite client in tests is easily accomplished with e.g. `with-redefs`:

```clojure
(defn my-http-function []
(let [response (client/get "https://example.org")]
(when (= 200 (:status response))
(:body response))))

(deftest my-http-function-test
(with-redefs [client/get (fn [_] {:status 200 :headers {"content-type" "text/plain"} :body "OK"})]
(is (= (my-http-function) "OK"))))
```

More advanced mocking may be performed by matching attributes in the `request`, like the `mock-response` function below.

```clojure
(ns http-test
(:require [clojure.data.json :as json]
[clojure.test :refer [deftest is testing]]
[clj-http.lite.client :as client]))

(defn send-report [data]
(:body (client/post "https://example.com/reports" {:body data})))

(defn get-users []
(json/read-str (:body (client/get "https://example.com/users"))))

(defn get-admin []
(let [response (client/get "https://example.com/admin")]
(if (= 200 (:status response))
(:body response)
"403 Forbidden")))

(defn mock-response [{:keys [url method body] :as request}]
(condp = [url method]
["https://example.com/reports" :post]
{:status 201 :headers {"content-type" "text/plain"} :body (str "created: " body)}

["https://example.com/users" :get]
{:status 200 :headers {"content-type" "application/json"} :body (json/write-str ["joe" "jane" "bob"])}

["https://example.com/admin" :get]
{:status 403 :headers {"content-type" "text/plain"} :body "forbidden"}

(throw (ex-info "unexpected request" request))))

(deftest send-report-test
(with-redefs [client/request mock-response]
(testing "sending report"
(is (= (send-report {:balance 100}) "created: {:balance 100}")))
(testing "list users"
(is (= (get-users) ["joe" "jane" "bob"])))
(testing "access admin page"
(is (= (get-admin) "403 Forbidden")))))
```

## GraalVM Native Image Tips

Expand Down