Unit testing 如何在使用msg抛出的测试中捕获IllegalArgumentException?

Unit testing 如何在使用msg抛出的测试中捕获IllegalArgumentException?,unit-testing,macros,clojure,Unit Testing,Macros,Clojure,我尝试测试异常的抛出: ;;; src ;; Courtesy https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj (defmacro assert-args [& pairs] `(do (when-not ~(first pairs) (throw (IllegalArgumentException. (str (first ~'&

我尝试测试异常的抛出:

;;; src
;; Courtesy https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj
(defmacro assert-args [& pairs]
  `(do (when-not ~(first pairs)
         (throw (IllegalArgumentException.
                 (str (first ~'&form) " requires " ~(second pairs) " in " ~'*ns* ":" (:line (meta ~'&form))))))
       ~(let [more (nnext pairs)]
          (when more
            (list* `assert-args more)))))

(defmacro my-macro []
  (assert-args false "foobar")
  #_(...))

;;; test
(deftest x-fn-test
  (is (thrown-with-msg? IllegalArgumentException #"foo" (my-macro))))

但是没有一个异常被测试框架捕获,而是全部抛出。

您的
throw
表达式格式不正确,您希望

(throw (IllegalArgumentException. "foo"))
完整工作代码:

(ns mytest.core
  (:use clojure.test))

(defn x-fn []
  (throw (IllegalArgumentException. "foo")))

(deftest x-fn-test
  (is (thrown-with-msg? IllegalArgumentException           #"foo"     (x-fn)))
  (is (thrown-with-msg? IllegalArgumentException           #".*foo.*" (x-fn)))
  (is (thrown-with-msg? IllegalArgumentException           #"^foo$"   (x-fn)))
  (is (thrown-with-msg? java.lang.IllegalArgumentException #"foo"     (x-fn)))
  (is (thrown-with-msg? java.lang.IllegalArgumentException #".*foo.*" (x-fn)))
  (is (thrown-with-msg? java.lang.IllegalArgumentException #"^foo$"   (x-fn))))


; nREPL 0.1.8-preview
user> 
#<Namespace mytest.core>
mytest.core> (run-tests)

Testing mytest.core

Ran 1 tests containing 6 assertions.
0 failures, 0 errors.
{:type :summary, :pass 6, :test 1, :error 0, :fail 0}
(ns mytest.core)
(:使用clojure.test)
(定义x-fn[]
(抛出(IllegalArgumentException.“foo”))
(deftest x-fn-test
(与msg?IllegalArgumentException#“foo”(x-fn)一起抛出)
(与msg?IllegalArgumentException#“*foo.*”(x-fn)一起抛出)
(与msg?IllegalArgumentException#“^foo$”(x-fn)一起抛出)
(与msg?java.lang.IllegalArgumentException#“foo”(x-fn)一起抛出)
(与msg?java.lang.IllegalArgumentException#“*foo.*”(x-fn)一起抛出)
(与msg?java.lang.IllegalArgumentException#“^foo$”(x-fn)一起抛出)
; nREPL 0.1.8-预览
用户>
#
mytest.core>(运行测试)
测试mytest.core
运行了1个包含6个断言的测试。
0次失败,0次错误。
{:类型:摘要,:通过6,:测试1,:错误0,:失败0}

仍然引发异常的原因是,宏
(我的宏)
在编译时被展开,调用
(assert args)
宏,因此在编译时引发异常。我的错误是假设在测试中调用
(我的宏)
将在运行时触发异常,并让测试的
(抛出msg?
捕获它


因此,错误的假设是,嵌套宏的代码只在编译时展开,而不是执行。如果
(我的宏)
是一个函数,那么它就可以工作了。

谢谢Joost,但这只是发布时的一个输入错误。问题仍然存在。或者它对你有用吗?Hej Joost,我被“示例谬误”困住了,并将示例代码简化到一个无法说明我的问题的程度。因此,这个例子对你有效。现在我发布了我的代码的一个非常接近的示例版本,这应该会暴露错误的假设。在将示例聚合到原始代码的过程中,我终于明白了发生了什么。我仍然支持你的答案,认为你在帮助别人方面所做的努力值得称赞。