Note that thrown?
and thrown-with-msg?
are two default implementations of the clojure.test/assert-expr
multimethod. You can make an implementation for handling clojure.lang.ExceptionInfo
or the CLJS equivalent. This is a straightforward implementation that compares the data, but you probably want to make this check for sub-maps (does the data you expect occur in the data returned).
(require '[clojure.test :as t :refer [deftest is do-report]])
(defmethod t/assert-expr 'thrown-with-data? [msg form]
(let [data (second form)
body (nthnext form 2)]
`(try ~@body
(do-report {:type :fail, :message ~msg,
:expected '~form, :actual nil})
(catch clojure.lang.ExceptionInfo e#
(let [expected# ~data
actual# (ex-data e#)]
(if (= expected# actual#)
(do-report {:type :pass, :message ~msg,
:expected expected#, :actual actual#})
(do-report {:type :fail, :message ~msg,
:expected expected#, :actual actual#})))
e#))))
(deftest foo
(is (thrown-with-data? {:a 1} (throw (ex-info "" {:a 1}))))
(is (thrown-with-data? {:b 1} (throw (ex-info "" {:a 1})))))
(t/run-tests)
$ clj /tmp/test.clj
Testing user
FAIL in (foo) (test.clj:24)
expected: {:b 1}
actual: {:a 1}
Ran 1 tests containing 2 assertions.
1 failures, 0 errors.
Bonus, also works in babashka:
$ bb /tmp/test.clj
Testing user
FAIL in (foo) (/private/tmp/test.clj:22)
expected: {:b 1}
actual: {:a 1}
Ran 1 tests containing 2 assertions.
1 failures, 0 errors.
{:test 1, :pass 1, :fail 1, :error 0, :type :summary}