gpt4 book ai didi

unit-testing - 如何在 clojure 中模拟宏以进行测试?

转载 作者:行者123 更新时间:2023-12-04 05:26:32 26 4
gpt4 key购买 nike

我想在命名空间中模拟一个宏。

例如,clojure.tools.logging/error .

我试过with-redefs没有运气

(def logged false)

(defmacro testerror
{:arglists '([message & more] [throwable message & more])}
[& args]
`(def logged true))

(deftest foo
...
(with-redefs
[log/error testerror]
...

这给出了这个错误: CompilerException java.lang.RuntimeException: Can't take value of a macro

最佳答案

Amalloy 为您提供了有关如何模拟宏的直接问题的答案 - 您不能。

但是,您可以使用其他解决方案来解决您的问题(比将整个应用程序移动到组件依赖注入(inject)更简单)。让我建议两个替代实现(不幸的是,不是很简单,但仍然比使用组件更简单)。

模拟日志宏调用的函数

您无法模拟宏,但可以模拟将在日志记录宏扩展时使用的函数。

(require '[clojure.tools.logging :as log])
(require '[clojure.pprint :refer [pprint]])

(pprint (macroexpand `(log/error (Exception. "Boom") "There was a failure")))

给出:
(let*
[logger__739__auto__
(clojure.tools.logging.impl/get-logger
clojure.tools.logging/*logger-factory*
#object[clojure.lang.Namespace 0x2c50fafc "boot.user"])]
(if
(clojure.tools.logging.impl/enabled? logger__739__auto__ :error)
(clojure.core/let
[x__740__auto__ (java.lang.Exception. "Boom")]
(if
(clojure.core/instance? java.lang.Throwable x__740__auto__)
(clojure.tools.logging/log*
logger__739__auto__
:error
x__740__auto__
(clojure.core/print-str "There was a failure"))
(clojure.tools.logging/log*
logger__739__auto__
:error
nil
(clojure.core/print-str x__740__auto__ "There was a failure"))))))

如您所见,执行实际日志记录的函数(如果启用给定级别)是通过 clojure.tools.logging/log* 完成的。功能。

我们可以模拟它并编写我们的测试:
(require '[clojure.test :refer :all])

(def log-messages (atom []))

(defn log*-mock [logger level throwable message]
(swap! log-messages conj {:logger logger :level level :throwable throwable :message message}))

(with-redefs [clojure.tools.logging/log* log*-mock]
(let [ex (Exception. "Boom")]
(log/error ex "There was a failure")
(let [logged (first @log-messages)]
(is (= :error (:level logged)))
(is (= "There was a failure!" (:message logged)))
(is (= ex (:throwable logged))))))

使用您的日志库 API 来收集和检查日志消息

您的日志库 API 可能会提供允许您插入测试以收集和断言日志事件的功能。例如 java.util.logging您可以编写自己的 Handler 实现这将收集所有记录的日志记录和 add it to a specific (or root) logger .

关于unit-testing - 如何在 clojure 中模拟宏以进行测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41813656/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com