我正在使用Timbre作为日志记录库,但我遇到了使用Midje对其进行测试的问题。我有以下方法,我想要做的就是声明Will be printed
已打印出来。
(defn init [level]
(timbre/merge-config! {:output-fn my-output-fn})
(timbre/set-level! level)
(timbre/info "Will be printed")
(timbre/debug "Won't be printed"))
通过将(timbre/default-output-fn)
包裹在我自己的my-output-fn
函数周围,我可以断言只打印了2个日志中的1个,这是真的:
(fact "print info but not debug"
(core/init :info) => nil
(provided
(core/my-output-fn anything) => irrelevant :times 1))
但是,我想确保正在打印的邮件是Will be printed
。我找不到任何办法,你会做什么?
我正在以下项目中进行实验https://github.com/stephanebruckert/timbre-midje
答案 0 :(得分:3)
可以使用Midje as-checker
prerequisite来验证函数的输入。
当您打印进入data
的{{1}}时(我通过您的timbre/default-output-fn
发现了这一点),您会看到它具有以下结构:
{:hash_ #delay [{:status:pending,:val nil} 0x5ed805b1] ,: instant #inst" 2016-10-14T17:07:16.779-00:00",:config { :level:info,....
因此output-fn
中提供了日志级别。使用data
as-checker
可以按如下方式验证:
log level
现在,您想要检查邮件的内容。不仅是日志级别。
实际消息在(fact "print info but not debug"
(core/init :info) => nil
(provided
(timbre/default-output-fn anything ; opts is first argument
(as-checker (fn [data]
(= (-> data :config :level) ; get log level
:info)))) ; validate that it is info
=> anything :times 1)
(provided
(timbre/default-output-fn anything
(as-checker (fn [data]
(= (-> data :config :level)
:debug))))
=> anything :times 0))
或opts
传递给data
时无效。在Timbre代码中查看,我看到它可以在私有函数default-output-fn
中使用vargs->margs
,?err
和msg-type
。 vargs
包含消息(在您的情况下,内容是vargs
。
通过:auto :p ["The message"])
方法可以验证消息如下:
as-checker
请注意(fact "print Will be printed, not Won't be printed"
(core/init :info) => nil
(provided
(#'timbre/vargs->margs anything anything ["Will be printed"]) => {} :times 1)
(provided
(#'timbre/vargs->margs anything anything ["Won't be printed"]) => {} :times 0) )
必须返回一个地图,否则Timbre会在以后的函数中抛出异常。
通过这种方式验证"将被打印"打印一次,"不打印"从未打印过。
答案 1 :(得分:2)
@ErwinRooijakkers的想法奏效,但@ptaoussanis on Github有充分的理由不去做。
请注意,
timbre/vargs->margs
是私有的,是一种实现方式 详情。它的行为可以随时改变,恕不另行通知 强烈建议不要以任何方式依赖它。可以使用自定义appender在某个地方发送输出,方便您的测试进行分析。您可以将这些appender设置为测试设置的一部分,和/或使用类似
timbre/with-config
的内容进行相应的测试调用。
所以我们可以添加一个appender来传递参数来检查(level
message
)到存根。
core.clj
(defn init
([level]
(init level {}))
([level config]
(timbre/merge-config! config)
(timbre/set-level! level)
(timbre/info "will be printed")
(timbre/debug "won't be printed")))
core_test.clj
(:require [timbre-midje.core :as core]
[midje.sweet :refer :all]))
(defn log-stub [level message])
(def log-stub-appender
{:appenders
{:test-appender
{:enabled? true
:fn (fn [data] (log-stub (:level data) (:vargs data)))}}})
(fact "print info but not debug"
(core/init :info log-stub-appender) => nil
(provided
(log-stub :info ["will be printed"]) => irrelevant :times 1
(log-stub :debug ["won't be printed"]) => irrelevant :times 0))