You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在测试中捕获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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 06:21:11