unit-testingclojuremidjetimbre

Testing Timbre log outputs with Midje


I am using Timbre as a logging library but I am having issues testing it with Midje. I've got the following method and all I'm trying to do is asserting that Will be printed is 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"))

By wrapping (timbre/default-output-fn) around a function of my own my-output-fn, I am able to assert that only 1 out of 2 logs are printed, which is true:

(fact "print info but not debug"
    (core/init :info) => nil
    (provided
        (core/my-output-fn anything) => irrelevant :times 1))

However I would like to make sure that the message being printed is Will be printed. I can't find any way of doing this, what would you do?

I am doing experiments in the following project https://github.com/stephanebruckert/timbre-midje


Solution

  • @ErwinRooijakkers' idea worked but @ptaoussanis on Github has a good reason not to do it.

    Please note that timbre/vargs->margs is private, and an implementation detail. Its behaviour can change at any time without notice, would strongly recommend not depending on it in any way.

    It'd be possible to use a custom appender that sends output somewhere that are handy for your tests to analyse. You could setup these appenders as part of your test setup, and/or use something like timbre/with-config for the appropriate test calls.

    So we can add an appender that passes the parameters to check (level message) to a stub.

    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))