2024年Clojure状态调查!中分享您的想法。

欢迎!请参见关于页面以了解更多关于它是如何工作的信息。

+1
Spec

函数有时可能抛出预期的异常。例如,函数 / 可能会抛出除以零异常。我如何使用spec来捕获这个异常?

3 答案

+2

被选中
 
最佳答案

简单的回答是“你不”。Spec可以讨论数据的结构和函数的转换行为,但异常绕过了这种行为:异常意味着函数没有要指定的结果。

那么,如果函数会抛出异常,我就不能进行任何生成性测试或函数仪器测试来检查函数的正确性吗?
生成测试涉及多次执行一个函数,这些函数使用随机生成的符合要求的参数,然后检查该函数的结果是否满足预期的属性。异常不是一种结果,因此,您不能对抛出异常的函数进行生成测试——除非您非常具体地定义参数,使其仅包含函数可以返回结果的值(这是Nikola的答案所暗示的)。
+2

与您的问题相关的方法是将异常转换为数据。

让异常在代码中流动可能会导致不必要的复杂化。您可以将可能会抛出异常的代码包裹在try/catch中,将异常转换为数据。

一旦异常变为从函数返回的数据,它就回到了规格化的领域。

您可以在cognitect-labs/anomalies库中看到这种方法。

同样,ex-info允许您为异常附加数据。

+1

Spec定义应使异常不可能发生

(defn myfn [x y] (/ x y))

(s/fdef myfn
  :args (s/cat :x number?
               :y (s/and
                   number?
                   (complement zero?))))

在开启仪器(在开发/测试期间)时,如果将0作为y传递给myfn,它将快速失败。参见:仪器化和测试

...