如何在测试中捕获Clojure宏展开时的编译器异常?
如何测试编译时触发的宏断言错误?
你的assert-keys函数是在宏展开阶段执行的,当传入无效键时,宏展开过程会直接抛出异常。要测试这个行为,你需要在测试中触发宏展开操作,并捕获对应的异常。以下是两种可行的测试方案:
方案1:直接测试宏展开过程
使用macroexpand-1直接触发宏展开,无需执行后续代码,测试更高效:
(ns your.test.namespace (:require [clojure.test :refer [deftest is thrown-with-msg?]] [your.core.namespace :refer [with-hooks]])) (deftest with-hooks-invalid-keys-test (is (thrown-with-msg? clojure.lang.ExceptionInfo #"Function call contains invalid key." (macroexpand-1 '(with-hooks {:read identity :invalid-key 123} (println "test")))))) (deftest with-hooks-valid-keys-test (is (some? (macroexpand-1 '(with-hooks {:read identity} (println "test"))))))
方案2:通过eval触发编译与执行
如果需要验证完整的编译+执行流程,可以用eval包裹有问题的代码,捕获编译阶段抛出的异常:
(deftest with-hooks-invalid-keys-eval-test (is (thrown-with-msg? clojure.lang.ExceptionInfo #"Function call contains invalid key." (eval '(with-hooks {:read identity :invalid-key 123} (println "test")))))) (deftest with-hooks-valid-keys-eval-test (is (nil? (eval '(with-hooks {:read identity} (println "test"))))))
关键说明
- 你的断言逻辑属于编译时检查:因为
assert-keys是在宏定义内部直接调用的,会在宏展开(编译阶段)执行,而非运行时。因此必须通过触发宏展开的操作(macroexpand-1/eval)来触发断言。 thrown-with-msg?用于验证异常类型和错误信息,确保抛出的是预期的断言异常。
内容的提问来源于stack exchange,提问作者Lars Melander
相关产品推荐
相关产品推荐

