Thank you so much, I tried this approach but in my case since our service is wrapped inside a component I ended up creating a macro I am using as a fixture to exercise the response-for
function
(defmacro with-mock-ds-system
[[sym ds-factory] & body]
;; Create a system map with a mock datastore and a mock auth-checker, set ::http/join == false so
;; that the system doesn't block execution.
`(let [temp# ~ds-factory]
;; Store a reference to this system, perhaps unnecessary but done for the sake
;; of future debuggability.
(reset! mock-svc (component/start-system (service/consent-service
(env/get-api-config)
(create-mock-auth-checker (env/get-api-config))
{:type :mockstore
:config temp#}
{:env :dev
::http/join? false})))
;; Pull the servlet function that is used for testing out of the newly created system.
(let [~sym (get-in @mock-svc [:consent :service ::http/service-fn])]
(try
~@body
;; Shutdown system.
(finally
(component/stop-system @mock-svc)
(reset! mock-svc nil))))))
And maybe an integration testing would be to compose "unit tests". for example - List resources: empty - Create resource: return resource - List resource: list with the created resource - Update the resource: return the updated resource ...and so on. Is this the idea of an integration testing?
I think that’s consistent with integration testing. In my experience, the term integration testing has been used to describe end-to-end tests which exercise the system in the context of backing infrastructure/dependencies (i.e., real database, externally deployed services, etc…)
For the unit test, we could also use let to get the response and use it to multiple "assertions"
(let [response (response-for service
:post "/foo"
:headers {"Content-Type" "application/json"}
:body "{\"foo\":\"bar\"}")]
(is (= 200 (:status response)))
(is (= {"foo": "bar"} (:body response))))