使用Midje测试音色日志输出



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

可以使用Midje的as-checker先决条件来验证函数的输入。

当你打印进入timbre/default-output-fndata时(我通过output-fn发现了这一点),你会看到它有以下结构:

{:hash_ #delay[{:status:pending,:val nil} 0x5ed805b1],:instant #inst "2016-10-14T17:07:16.779-00:00",:config {:level:info, ....

所以日志级别在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))

现在,您想要检查消息的内容。不仅是日志级别。

传递给default-output-fnoptsdata中实际消息不可用。在音色代码中,我看到它可以在私有函数vargs->margs中使用,该函数需要?err, msg-typevargsvargs包含消息(在您的情况下,例如: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) )

注意vargs->margs必须返回一个映射,否则Timbre会在后面的函数中抛出异常。

这样可以验证"Will be printing "只打印一次,而"Won't be printing "不打印。

@ErwinRooijakkers的想法奏效了,但Github上的@ptaoussanis有一个很好的理由不这样做。

请注意timbre/vargs->margs是私有的,并且是一个实现细节。它的行为可以在没有通知的情况下随时改变强烈建议不要以任何方式依赖它。

可以使用自定义appender将输出发送到方便测试分析的地方。您可以将这些appender设置为测试设置的一部分,并且/或使用timbre/with-config之类的东西进行适当的测试调用。

因此,我们可以添加一个追加器,将要检查的参数(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))

最新更新