我最喜欢的方法是使用tupelo.test 库,如this template project 所示。例如:
(ns tst.demo.core
(:use tupelo.core tupelo.test))
(dotest
(is= 5 (+ 2 3))
(throws? (/ 1 0)))
结果
-----------------------------------
Clojure 1.10.3 Java 15.0.2
-----------------------------------
Testing tst.demo.core
Ran 2 tests containing 2 assertions.
0 failures, 0 errors.
如果throws? 中的表达式没有抛出异常,它将失败。否则就是通过测试。
这在后台使用try/catch,您也可以随时手动执行。
如果您真的不想使用库,您可以在clojure.test 中进行操作。您需要使用如下语法:
(is (thrown? ArithmeticException (/ 1 0)))
但是,请注意,此功能很脆弱,如果您犯了错误,您将不会收到任何警告。这就是我编写包装器 tupelo.test/throws? 的原因,因为它既简单又防弹。
由于 Tupelo 库是开源的,您可以随时复制源代码:
(defmacro throws?
"Use (throws? ...) instead of (is (thrown? ...)) for clojure.test. Usage:
(throws? (/ 1 0)) ; catches any Throwable"
[& forms]
`(clojure.test/is
(try
~@forms
false ; fail if no exception thrown
(catch Throwable dummy#
true)))) ; if anything is thrown, test succeeds
因此您可以看到,throws? 宏所做的所有工作就是将您的代码包装在 try/catch 中,然后将 true 或 false 返回到标准的 clojure.test/is 表单。