ClojureScript Spec断言未触发异常:非整数键映射未触发断言
解决ClojureScript Spec未触发整数键映射校验的问题
我懂你的困扰——你已经给next-int-key函数定义了Spec规则,要求传入的映射必须全是整数键,但调用时传入非整数键的map却没触发预期的断言异常。这其实是因为ClojureScript的Spec默认不会自动启用运行时参数校验,你需要手动开启这个功能才行。
问题根源
你写的s/fdef只是给函数定义了规格描述,但Spec不会自动拦截函数调用并校验参数。要让Spec在运行时检查参数是否符合定义,必须使用instrument工具来启用校验。
解决方案步骤
引入Spec测试命名空间
首先需要引入cljs.spec.test.alpha,它包含了instrument函数,用于启用运行时校验:(ns project.utils (:require [cljs.spec.alpha :as s] [cljs.spec.test.alpha :as stest]))启用函数的运行时校验
在定义完fdef之后,调用stest/instrument来启用当前命名空间下所有带有fdef的函数的校验,或者指定只校验next-int-key:(defn next-int-key "Return the next integer key for a integer keyed map." [m] (if (empty? m) 0 (+ 1 (apply max (keys m))))) (s/fdef next-int-key :args (s/cat :m (s/map-of int? some?)) :ret int?) ; 启用当前命名空间所有带fdef的函数的校验 (stest/instrument) ; 或者只启用单个函数的校验 ; (stest/instrument 'project.utils/next-int-key)验证校验效果
现在调用(next-int-key {"a" 1}),就会触发Spec的断言异常,提示传入的映射不符合(s/map-of int? some?)的规格要求,和你预期的一致。
生产环境注意事项
运行时校验会带来一定的性能开销,所以建议只在开发环境启用。你可以通过ClojureScript的goog.DEBUG标志来条件启用:
(when ^boolean js/goog.DEBUG (stest/instrument))
这样只有在开发模式下(goog.DEBUG为true)才会开启校验,生产环境自动跳过。
内容的提问来源于stack exchange,提问作者afunkyrobot
相关产品推荐
相关产品推荐

