首页 > 解决方案 > 如何在 Clojure 测试中停用日志?

问题描述

问题

我想在我的测试机构中像黑洞print一样的行为,以保持我的日志输出看起来干净整洁。

(deftest some-test
   (testing "something"
      (logless 
         (is (= 22 (test-thing 14))))))

我希望调用 test-thingprintln和其他类似的调用,*out*并希望那些停止污染我的测试输出。

一般有公认的方法来做到这一点吗?

我找到了这个人(with-out-str),但它正在捕获字符串,而不是我想要的。

背景

我对 Clojure 相当陌生,主要来自 javascript 世界。到目前为止玩得很开心!但是我还有很多东西要学。

在 Clojure 中,而不是 Clojure.script(如果重要的话)

标签: testingloggingclojure

解决方案


只需使用with-out-str然后忽略字符串。

请注意,这不会从 Java 库中捕获错误消息或消息。如果您想捕获和/或抑制此输出,我在Tupelo 库中编写了 3 个附加函数,您可能会发现它们很有用:

代码如下所示:

   (defmacro with-system-err-str
     "Evaluates exprs in a context in which JVM System/err is bound to a fresh
     PrintStream.  Returns the string created by any nested printing calls."
     [& body]
     `(let [baos# (ByteArrayOutputStream.)
            ps#   (PrintStream. baos#)]
        (System/setErr ps#)
        ~@body
        (System/setErr System/err)
        (.close ps#)
        (.toString baos#)))

如果你愿意,你可以像这样创建一个新的宏:

(defmacro with-printing-suppressed
  "Evaluates exprs in a context in which JVM System/err and System/out captured & discarded."
  [& body]
  `(let [baos# (ByteArrayOutputStream.)
         ps#   (PrintStream. baos#)
         s#    (new java.io.StringWriter)]
     (System/setErr ps#)
     (System/setOut ps#)
     (binding [*err* s#
               *out* s#]
       (let [result# (do ~@body)]
         (.close ps#)
         (System/setErr System/err)
         (System/setOut System/out)
         result#))))

(defn stuff []
  (println "***** doing stuff *****")
  42)

然后测试它:

  (println "calling - before")
  (is= 42 (with-printing-suppressed 
            (stuff)))
  (println "calling - after")

结果:

calling - before
calling - after

推荐阅读