[英]Why can't with-redefs be applied around a deftest?
The with-redefs function appears to be just what is needed to mock/stub out dependencies in clojure tests. with-redefs function 似乎正是在 clojure 测试中模拟/存根依赖项所需要的。 I'm using clojure.test [1.10.1]
我正在使用 clojure.test [1.10.1]
Initially it gave me a lot of grief, where the new bindings were not applied when I ran the test.最初它给了我很多悲伤,当我运行测试时没有应用新的绑定。 Finally I got the following setup to work as expected.
最后我得到了以下设置按预期工作。 The dependencies are required from other namespaces
其他命名空间需要依赖项
(ns abc
(:require [anotherns.id-gen-mock :as mock])
(deftest test-buy
(testing "Appends trade to the trades log"
(let [mock (atom {})]
(with-redefs [id-gen/get-next-id mock/get-next-id
save-trade (fn [t] (reset! mock {:trade t}))]
... test code
))))
Now I realized, that the mocks can be common to all my tests, so I moved it up like so.现在我意识到,我所有的测试都可以使用模拟,所以我把它向上移动了。
(with-redefs [id-gen/get-next-id mock/get-next-id
save-trade identity]
(deftest test-holdings
(testing "after 1 buy"
... test code
Now the new bindings are not used, the real dependencies are invoked - failing the test.现在没有使用新的绑定,调用了真正的依赖项——测试失败。
I see some posts on SO mentioning something about "direct linking" but I couldn't really fathom why it works in Case1 but not in Case2.我看到一些关于 SO 的帖子提到了一些关于“直接链接”的内容,但我无法理解为什么它在 Case1 中有效,但在 Case2 中无效。 If I move with-redefs back under the deftest form, it works again.
如果我将 with-redefs 移回 deftest 表单下,它会再次起作用。
According to the docstring ( https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-redefs ), with-redefs restores the original value after executing the body.根据文档字符串( https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-redefs ),with-redefs 执行主体后恢复原始值。 In the given case, the body defines a test.
在给定的情况下,主体定义了一个测试。 With-redefs thus governs the tests' definition, but not their execution.
因此,with-redefs 控制测试的定义,但不控制它们的执行。 When the tests execute, any reference to get-next-id resolves that symbol to its current value, which by that time will be the real one, not the mock.
当测试执行时,任何对 get-next-id 的引用都会将该符号解析为其当前值,到那时它将是真实的,而不是模拟的。 (This follows logically: if case No.1 holds, and the docstring holds, then case No.2 could not hold.)
(这在逻辑上是这样的:如果 case No.1 成立,并且 docstring 成立,那么 case No.2 不能成立。)
For reasons already mentioned in comments, with-redefs is not usually a tool of first choice.由于评论中已经提到的原因,with-redefs 通常不是首选工具。 Clojure offers more robust techniques, eg, make higher-order subsystems and use fixtures to configure them for testing.
Clojure 提供了更强大的技术,例如,制作高阶子系统并使用夹具对其进行配置以进行测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.