有一些基本的东西,我没有到这里来。我希望以下测试通过。但是第二个测试用例“staging”/“staging”失败了。它好像with-redefs-fn无法通过测试用例实例。但伐木说一切都很好。这很令人困惑。
(deftest test-bad-derive-s3-environment
(testing "variants of props environments"
(doseq [test-case [{:env "qa1" :expect "qa1"}
{:env "dev" :expect "qa1"}
{:env "staging" :expect "staging"}]]
(log/infof "test-case %s" test-case)
(with-redefs-fn {#'config/environment (fn [] (:env test-case))}
(let [actual (fs/derive-s3-environment (config/environment))
_ (log/infof "within redefs :env %s :expect %s" (:env test-case) (:expect test-case))]
#(is (= actual (:expect test-case))))))))
...
lein test com.climate.test.mapbook.filestore
2016-05-03 16:16:29,353 INFO filestore:288 - test-case {:env "qa1", :expect "qa1"}
2016-05-03 16:16:29,355 INFO EnvConfig:98 - Loading config properties from /export/disk0/wb/etc/env.properties
2016-05-03 16:16:29,357 INFO EnvConfig:98 - Loading config properties from /export/disk0/wb/etc/local.properties
2016-05-03 16:16:29,358 INFO filestore:288 - within redefs :env qa1 :expect qa1
2016-05-03 16:16:29,359 INFO filestore:288 - test-case {:env "staging", :expect "staging"}
2016-05-03 16:16:29,359 INFO filestore:288 - within redefs :env staging :expect staging
lein test :only com.climate.test.mapbook.filestore/test-bad-derive-s3-environment
FAIL in (test-bad-derive-s3-environment) (filestore.clj:29)
variants of props environments
expected: (= actual (:expect test-case))
actual: (not (= "qa1" "staging"))
2016-05-03 16:16:29,364 INFO filestore:288 - test-case {:env "dev", :expect "qa1"}
2016-05-03 16:16:29,364 INFO filestore:288 - within redefs :env dev :expect qa1
为什么我的with-redefs-fn无法根据当前的测试用例重新定义配置/环境功能?
答案 0 :(得分:2)
首先,请注意您的最终测试实例具有:expect
"qa1"
- 与第一个测试实例相同 - 因此如果代码按预期工作,它实际上应该失败;它的传递是与第二个实例失败相同问题的症状。
现在进行修复 - 有两种选择:
只需使用with-redefs
代替with-redefs-fn
:
(with-redefs [config/environment (fn [] (:env test-case))]
…)
大部分时间这都是你想要做的,你可以认为with-redefs-fn
是with-redefs
背后的实现细节 - 虽然严格来说它确实有一些实用性,因为它可以重新定义动态构建的Vars集合。
使用with-redefs-fn
,但将内部let
表单移到匿名函数中:
(with-redefs-fn {…}
#(let […]
(is …)))
最后,这些工作的原因和问题文本中的版本不是:
在闭包内部移动 日志打印输出很好,因为它们只关注with-redefs-fn
是一个函数,因此在运行时,它的参数将在实际调用它们的运行时值之前进行计算。特别是,作为第二个参数传入的let
表达式将在重新定义发生之前进行评估,因此本地调用actual
将获得在重新定义之前评估(config/environment)
的结果作为其值,并且将安装该值在let
的正文中创建的匿名闭包中。然而,该闭包将在重新定义的情况下被调用,因此它将在重新定义之前采用其“实际”值的概念,并将其与重新定义之后的期望值进行比较,从而产生观察到的行为。 / p>
let
,如上面的第二种方法,修复了这个不匹配问题 - let
local的值是通过重新定义来计算的,一切都很好。使用with-redefs
的第一种方法扩展到第二种方法。doseq
本地,而且从不检查任何Vars。如果他们这样做,他们只会看到预重定义值。