Im taking a look at the test examples generated by duct
:
(deftest smoke-test
(testing "example page exists"
(let [handler (ig/init-key :delme.handler/example {})
response (handler (mock/request :get "/example"))]
(is (= 200 (:status response)) "response ok"))))
You can move the handler creation to its own function, and then use a fixture (see (https://clojuredocs.org/clojure.test/use-fixtures) to call that function before running the namespace tests
but how can I pass data from a fixture to the test?
Ok, so there are two possible approaches. If you want to use the same handler in different deftest
functions, you want to keep the handler in a top-level var. E.g., you could create an atom to hold all the handlers (and other system elements) that you want to use in several deftest
s. You add/remove them in your fixture, and access (use) them in our tests through the atom.
This is a skeleton of this idea (might have slight errors, I didn't test it in the REPL):
(def system (atom {}))
(defn init-handler []
(ig/init-key :delme.handler/example {}))
(defn halt-handler [system]
(ig/halt-key! system))
(defn init-halt-handler [f]
(reset! system (init-handler))
(f)
(halt-handler @system))
(use-fixtures :once init-halt-handler)
(deftest smoke-test
(let [handler (:delme.handler/example @system)
....))
(deftest another-smoke-test
(let [handler (:delme.handler/example @system)
....))
(deftest even-another-smoke-test
(let [handler (:delme.handler/example @system)
....))
The other approach is to have multiple testing
block in a single deftest
. In that case, you have a let
block in the deftest
defining your handler (and every other system element you want to use in your tests) and use them from your testing
blocks. E.g.
clj
(deftest smoke-test
(let [handler (ig/init-key :delme.handler/example {})]
(testing "example page exists"
(let [response (handler (mock/request :get "/example"))]
(is (= 200 (:status response)) "response ok")))
(testing "example2 page exists"
(let [response (handler (mock/request :get "/example2"))]
(is (= 200 (:status response)) "response ok")))
;; More `testing` blocks here...
(testing "example3 page does not exist"
(let [response (handler (mock/request :get "/example3"))]
(is (= 404 (:status response)) "page not found")))))
I wonder if there is a way to create the handler once and use it on every test of the namespace instead of creating it every test
looking at my init output there is something strange:
2020-05-31 17:41:46.848:INFO::main: Logging initialized @6356ms
2020-05-31 17:41:53.310:INFO::main: Logging initialized @6354ms
2020-05-31 17:41:53.415:INFO:oejs.Server:main: jetty-9.2.21.v20170120
2020-05-31 17:41:53.449:INFO:oejs.ServerConnector:main: Started ServerConnector@6701a904{HTTP/1.1}{0.0.0.0:3000}
2020-05-31 17:41:53.450:INFO:oejs.Server:main: Started @6494ms
why there are two rows with logging initialized?
2020-05-31 17:41:46.848:INFO::main: Logging initialized @6356ms
2020-05-31 17:41:53.310:INFO::main: Logging initialized @6354ms
am I initializing the logger twice?my config looks like this
{:duct.profile/base
{:duct.core/project-ns zendesk-app
:zendesk-app.handler.core/handler {}
:duct.server.http/jetty {:handler #ig/ref :zendesk-app.handler.core/handler
:port 3000
:join? false
:logger #ig/ref :duct.logger/timbre}}
:duct.profile/dev #duct/include "dev"
:duct.profile/local #duct/include "local"
:duct.profile/prod {}
:duct.module/logging {}}