嘲笑中的棘手行为* out *

时间:2014-06-08 12:35:39

标签: clojure mocking

我有这段代码:

(def x 10)

(def io (java.io.StringWriter.))

(with-redefs [x 11]
  (with-redefs [io (java.io.StringWriter.)]
    (.write io "one"))
  (with-redefs [io (java.io.StringWriter.)]
    (.write io "two")
    (.toString io)))

(with-redefs [x 11]
  (with-redefs [*out* (java.io.StringWriter.)]
    (print "one"))
  (with-redefs [*out* (java.io.StringWriter.)]
    (print "two")
    (.toString *out*)))

第一个with-redefs块返回"两个"正如所料。第二个返回" onetwo"。就好像它出于某种原因重新使用同样的模拟**一样。这是预期的行为吗?

1 个答案:

答案 0 :(得分:2)

问题在于,您关心的*out*是线程本地的,而不是根值。尝试:

(with-redefs [x 11]
  (binding [*out* (java.io.StringWriter.)]
    (print "one"))
  (binding [*out* (java.io.StringWriter.)]
    (print "two")
  (.toString *out*)))

with-redefs宏仅改变根绑定;任何线程本地绑定都不受影响。当代码由REPL服务器执行时,它是在将*out*重新绑定到客户端特定的编写器的上下文中完成的,这样就可以捕获输出并将其发送回客户端以供显示(否则它会转到服务器的标准输出。如果从命令行而不是REPL运行,原始代码可能会起作用。