clojure.test 抛出?不在 repl 中工作
clojure.test throws? not working in the repl
根据 clojure.test
源代码中的文档字符串,我在 repl 中发出以下内容:
(use 'clojure.test)
(is (thrown? ArithmeticException (/ 1 0)))
以及其他变体,例如将 ArithmeticException 替换为 java.lang.ArithmeticException。然而,异常从未被 clojure.test 捕获,而是一直冒到顶部:
> #error { :cause "Divide by zero" :via [{:type java.lang.ArithmeticException :message "Divide by zero" :at
> [clojure.lang.Numbers divide "Numbers.java" 158]}] :trace
> [[clojure.lang.Numbers divide "Numbers.java" 158]
> [clojure.lang.Numbers divide "Numbers.java" 3808] [api.core$eval1305
> invokeStatic "form-init8750388124499546857.clj" 1]
> [api.core$eval1305 invoke "form-init8750388124499546857.clj" 1]
> [clojure.lang.Compiler eval "Compiler.java" 6927]
> [clojure.lang.Compiler eval "Compiler.java" 6890] [clojure.core$eval
> invokeStatic "core.clj" 3105] [clojure.core$eval invoke "core.clj"
> 3101] [clojure.main$repl$read_eval_print__7408$fn__7411 invoke
> "main.clj" 240] [clojure.main$repl$read_eval_print__7408 invoke
> "main.clj" 240] [clojure.main$repl$fn__7417 invoke "main.clj" 258]
> [clojure.main$repl invokeStatic "main.clj" 258] [clojure.main$repl
> doInvoke "main.clj" 174] [clojure.lang.RestFn invoke "RestFn.java"
> 1523]
> [clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__667
> invoke "interruptible_eval.clj" 87] [clojure.lang.AFn applyToHelper
> "AFn.java" 152] [clojure.lang.AFn applyTo "AFn.java" 144]
> [clojure.core$apply invokeStatic "core.clj" 646]
> [clojure.core$with_bindings_STAR_ invokeStatic "core.clj" 1881]
> [clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1881]
> [clojure.lang.RestFn invoke "RestFn.java" 425]
> [clojure.tools.nrepl.middleware.interruptible_eval$evaluate
> invokeStatic "interruptible_eval.clj" 85]
> [clojure.tools.nrepl.middleware.interruptible_eval$evaluate invoke
> "interruptible_eval.clj" 55]
> [clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__712$fn__715
> invoke "interruptible_eval.clj" 222]
> [clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__707
> invoke "interruptible_eval.clj" 190] [clojure.lang.AFn run
> "AFn.java" 22] [java.util.concurrent.ThreadPoolExecutor runWorker
> "ThreadPoolExecutor.java" 1142]
> [java.util.concurrent.ThreadPoolExecutor$Worker run
> "ThreadPoolExecutor.java" 617] [java.lang.Thread run "Thread.java"
> 745]]}
可能是什么?
clojure.test 中的其他内容确实在 repl 中按预期工作。
版本信息:
Leiningen 2.7.1 on Java 1.8.0_101 Java HotSpot(TM) 64-Bit Server VM
> nREPL server started on port 44025 on host 127.0.0.1 -
> nrepl://127.0.0.1:44025 REPL-y 0.3.7, nREPL 0.2.12 Clojure 1.8.0 Java
> HotSpot(TM) 64-Bit Server VM 1.8.0_101-b13
在(clojure.test/
deftest...)
中使用it/wrap
假设:
(require '[clojure.test :as t])
通过示例
(t/deftest a
(t/testing "a test"
(t/is (thrown? ArithmeticException (/ 1 0)))))
(a)
nil
失败示例
(t/deftest a
(t/testing "a test"
(t/is (thrown? NullPointerException (/ 1 0)))))
(a)
; ERROR in (a) (Numbers.java:158)
; a test
; expected: (thrown? NullPointerException (/ 1 0))
; actual: java.lang.ArithmeticException: Divide by zero
您还可以使用 t/run-tests
获得 summary/stats
或者你似乎可以像这样直接使用 t/test-var
(t/test-var (t/is (thrown? ArithmeticException (/ 1 0))))
nil
您可能还对 throws?
宏感兴趣
from the Tupelo library。它更通用,
比 clojure.test
中的 thrown?
子句更易于使用。请注意 clojure.test
中的 thrown?
不是正常的
Clojure 函数或宏,但是是仅在 is
宏中识别的自定义表达式。
tupelo.test/throws?
宏是一个普通的 Clojure 宏,可以在任何地方使用。
throws?
应单独使用,不应包含在 is
语句中。
请注意,throws?
始终 returns true
或 false
,可用于进一步处理。
> lein repl
user=> (use 'tupelo.test)
user=> (throws? (/ 1 0))
true ; <= return value
user=> (throws? Exception (/ 1 0))
true ; <= return value
user=> (throws? ArithmeticException (/ 1 0))
true ; <= return value
如果表达式没有抛出异常,或者抛出不同类型的异常,那么
throws?
将通过 (clojure.test/is false)
注册失败的测试,并且还将 return false
:
user=> (throws? NullPointerException (/ 1 0))
FAIL in () (form-init2868942318552383212.clj:1)
expected: (try (/ 1 0) false (catch NullPointerException t1__13775__auto__ true) (catch java.lang.Throwable t2__13776__auto__ false))
actual: false
false ; <= return value
clj.core=> (throws? ArithmeticException (+ 1 0))
FAIL in () (form-init4299343763551622058.clj:1)
expected: (try (+ 1 0) false (catch ArithmeticException t1__13761__auto__ true) (catch java.lang.Throwable t2__13762__auto__ false))
actual: false
false ; <= return value
clj.core=> (throws? (+ 1 0))
FAIL in () (form-init4299343763551622058.clj:1)
expected: (try (+ 1 0) false (catch java.lang.Throwable t3__13763__auto__ true))
actual: false
false ; <= return value
throws?
的典型用法由 tupelo.core 自己的单元测试说明:
(ns test.tupelo.core
(:use clojure.test tupelo.test )
(:require [tupelo.core :as t] ))
(t/refer-tupelo)
(deftest t-grab
(let [map1 {:a 1 :b 2}]
(is= 1 (grab :a map1))
(is= 2 (grab :b map1))
(throws? (grab :c map1)) ))
根据 clojure.test
源代码中的文档字符串,我在 repl 中发出以下内容:
(use 'clojure.test)
(is (thrown? ArithmeticException (/ 1 0)))
以及其他变体,例如将 ArithmeticException 替换为 java.lang.ArithmeticException。然而,异常从未被 clojure.test 捕获,而是一直冒到顶部:
> #error { :cause "Divide by zero" :via [{:type java.lang.ArithmeticException :message "Divide by zero" :at
> [clojure.lang.Numbers divide "Numbers.java" 158]}] :trace
> [[clojure.lang.Numbers divide "Numbers.java" 158]
> [clojure.lang.Numbers divide "Numbers.java" 3808] [api.core$eval1305
> invokeStatic "form-init8750388124499546857.clj" 1]
> [api.core$eval1305 invoke "form-init8750388124499546857.clj" 1]
> [clojure.lang.Compiler eval "Compiler.java" 6927]
> [clojure.lang.Compiler eval "Compiler.java" 6890] [clojure.core$eval
> invokeStatic "core.clj" 3105] [clojure.core$eval invoke "core.clj"
> 3101] [clojure.main$repl$read_eval_print__7408$fn__7411 invoke
> "main.clj" 240] [clojure.main$repl$read_eval_print__7408 invoke
> "main.clj" 240] [clojure.main$repl$fn__7417 invoke "main.clj" 258]
> [clojure.main$repl invokeStatic "main.clj" 258] [clojure.main$repl
> doInvoke "main.clj" 174] [clojure.lang.RestFn invoke "RestFn.java"
> 1523]
> [clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__667
> invoke "interruptible_eval.clj" 87] [clojure.lang.AFn applyToHelper
> "AFn.java" 152] [clojure.lang.AFn applyTo "AFn.java" 144]
> [clojure.core$apply invokeStatic "core.clj" 646]
> [clojure.core$with_bindings_STAR_ invokeStatic "core.clj" 1881]
> [clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1881]
> [clojure.lang.RestFn invoke "RestFn.java" 425]
> [clojure.tools.nrepl.middleware.interruptible_eval$evaluate
> invokeStatic "interruptible_eval.clj" 85]
> [clojure.tools.nrepl.middleware.interruptible_eval$evaluate invoke
> "interruptible_eval.clj" 55]
> [clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__712$fn__715
> invoke "interruptible_eval.clj" 222]
> [clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__707
> invoke "interruptible_eval.clj" 190] [clojure.lang.AFn run
> "AFn.java" 22] [java.util.concurrent.ThreadPoolExecutor runWorker
> "ThreadPoolExecutor.java" 1142]
> [java.util.concurrent.ThreadPoolExecutor$Worker run
> "ThreadPoolExecutor.java" 617] [java.lang.Thread run "Thread.java"
> 745]]}
可能是什么? clojure.test 中的其他内容确实在 repl 中按预期工作。
版本信息:
Leiningen 2.7.1 on Java 1.8.0_101 Java HotSpot(TM) 64-Bit Server VM
> nREPL server started on port 44025 on host 127.0.0.1 -
> nrepl://127.0.0.1:44025 REPL-y 0.3.7, nREPL 0.2.12 Clojure 1.8.0 Java
> HotSpot(TM) 64-Bit Server VM 1.8.0_101-b13
在(clojure.test/
deftest...)
假设:
(require '[clojure.test :as t])
通过示例
(t/deftest a
(t/testing "a test"
(t/is (thrown? ArithmeticException (/ 1 0)))))
(a)
nil
失败示例
(t/deftest a
(t/testing "a test"
(t/is (thrown? NullPointerException (/ 1 0)))))
(a)
; ERROR in (a) (Numbers.java:158)
; a test
; expected: (thrown? NullPointerException (/ 1 0))
; actual: java.lang.ArithmeticException: Divide by zero
您还可以使用 t/run-tests
获得 summary/stats
或者你似乎可以像这样直接使用 t/test-var
(t/test-var (t/is (thrown? ArithmeticException (/ 1 0))))
nil
您可能还对 throws?
宏感兴趣
from the Tupelo library。它更通用,
比 clojure.test
中的 thrown?
子句更易于使用。请注意 clojure.test
中的 thrown?
不是正常的
Clojure 函数或宏,但是是仅在 is
宏中识别的自定义表达式。
tupelo.test/throws?
宏是一个普通的 Clojure 宏,可以在任何地方使用。
throws?
应单独使用,不应包含在 is
语句中。
请注意,throws?
始终 returns true
或 false
,可用于进一步处理。
> lein repl
user=> (use 'tupelo.test)
user=> (throws? (/ 1 0))
true ; <= return value
user=> (throws? Exception (/ 1 0))
true ; <= return value
user=> (throws? ArithmeticException (/ 1 0))
true ; <= return value
如果表达式没有抛出异常,或者抛出不同类型的异常,那么
throws?
将通过 (clojure.test/is false)
注册失败的测试,并且还将 return false
:
user=> (throws? NullPointerException (/ 1 0))
FAIL in () (form-init2868942318552383212.clj:1)
expected: (try (/ 1 0) false (catch NullPointerException t1__13775__auto__ true) (catch java.lang.Throwable t2__13776__auto__ false))
actual: false
false ; <= return value
clj.core=> (throws? ArithmeticException (+ 1 0))
FAIL in () (form-init4299343763551622058.clj:1)
expected: (try (+ 1 0) false (catch ArithmeticException t1__13761__auto__ true) (catch java.lang.Throwable t2__13762__auto__ false))
actual: false
false ; <= return value
clj.core=> (throws? (+ 1 0))
FAIL in () (form-init4299343763551622058.clj:1)
expected: (try (+ 1 0) false (catch java.lang.Throwable t3__13763__auto__ true))
actual: false
false ; <= return value
throws?
的典型用法由 tupelo.core 自己的单元测试说明:
(ns test.tupelo.core
(:use clojure.test tupelo.test )
(:require [tupelo.core :as t] ))
(t/refer-tupelo)
(deftest t-grab
(let [map1 {:a 1 :b 2}]
(is= 1 (grab :a map1))
(is= 2 (grab :b map1))
(throws? (grab :c map1)) ))