clojure.test抛出?不在repl工作

时间:2017-03-28 12:54:48

标签: clojure leiningen

关注clojure.test来源中的docstring,我在repl中发出以下内容:

(use 'clojure.test)
(is (thrown? ArithmeticException (/ 1 0)))

其他变体,例如用 java.lang.ArithmeticException 替换 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位服务器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

2 个答案:

答案 0 :(得分:3)

使用它/将其包装在(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获取摘要/统计信息

或者似乎你可以直接使用t/test-var

(t/test-var (t/is (thrown? ArithmeticException (/ 1 0))))
nil

答案 1 :(得分:2)

您可能也对throws?宏感兴趣  from the Tupelo library。它更通用 比thrown?中的clojure.test子句更容易使用。请注意thrown?中的clojure.test不正常 Clojure函数或宏,但是只在is宏中识别的自定义表达式。

tupelo.test/throws?宏是一个普通的Clojure宏,可以在任何地方使用。

throws?旨在单独使用,不应包含在is语句中。 请注意,throws?始终返回truefalse,可用于进一步处理。

> 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)注册失败的测试,并返回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

tupelo.core自己的单元测试说明了throws?的典型用法:

(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)) ))