使用Midje测试Timbre日志输出

时间:2016-10-10 18:21:01

标签: unit-testing clojure midje timbre

我正在使用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

2 个答案:

答案 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?errmsg-typevargs包含消息(在您的情况下,内容是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))