Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 使用redefs fn无法从do seq获取绑定?_Clojure - Fatal编程技术网

Clojure 使用redefs fn无法从do seq获取绑定?

Clojure 使用redefs fn无法从do seq获取绑定?,clojure,Clojure,有些基本的东西我不明白。我希望下面的测试能通过。但是第二个测试用例“staging”/“staging”失败。就好像redefs fn无法通过测试用例实例一样。但是日志显示一切正常。这令人困惑 (deftest test-bad-derive-s3-environment (testing "variants of props environments" (doseq [test-case [{:env "qa1" :expect "qa1"}

有些基本的东西我不明白。我希望下面的测试能通过。但是第二个测试用例“staging”/“staging”失败。就好像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

为什么my with redefs fn无法根据当前测试用例重新定义配置/环境功能?

首先,请注意,您的最终测试实例有一个
:expect
“qa1”
——与第一个测试实例相同——因此,如果代码按照您的预期工作,它实际上应该失败;它的通过与第二个实例的失败是同一问题的征兆

现在,解决方案有两个选项:

  • 只需将
    与redefs一起使用,而不是将
    与redefs一起使用fn

    (with-redefs [config/environment (fn [] (:env test-case))]
      …)
    

    大多数时候这就是你想做的事情,你可以考虑用ReFDES FN<代码> <代码>是代码后面的一个实现细节,用ReDefs——尽管严格地说,它本身也有一些实用性,因为它可以重新定义动态构建的VARS集合。

  • 与redefs fn一起使用,但将内部
    let
    表单移动到匿名函数中:

    (with-redefs-fn {…}
      #(let […]
         (is …)))
    
  • 最后,这些工作的原因和问题文本中的版本不:


    with redefs fn
    是一个函数,因此在运行时,它的参数将在实际调用之前进行计算,并传递运行时值。特别是,作为第二个参数传入的
    let
    表达式将在重新定义之前进行求值,因此被称为
    实际值的本地表达式将在重新定义之前获得求值
    (配置/环境)
    的结果作为其值,该值将安装在
    let
    主体中创建的匿名闭包中。然而,当重新定义到位时,将调用该闭包,因此它将从重新定义之前获取其“实际”值的概念,并将其与重新定义后设定的期望值进行比较,从而得出观察到的行为

    在闭包内移动
    let
    ,就像上面的第二种方法一样,修复了这个不匹配的问题–在重新定义到位的情况下计算
    let
    local的值,一切正常。将
    与redefs一起使用的第一种方法扩展到第二种方法


    日志打印输出很好,因为它们只与
    doseq
    本地相关,从不检查任何变量。如果他们这样做了,他们只会看到预先重新定义的值。

    我现在正努力理解redefs fn的效用。with redefs的工作原理与champ类似。
    with redefs fn
    是一个实现细节–它存在并且是公共的,因此with redefs
    可以在其扩展中使用它。用户代码通常不应该直接调用它。也许我应该在回答中提到这一点!事实上,我收回这句话。大多数情况下,使用redefs的
    更方便,但是使用redefs的
    fn
    允许重新定义动态创建的变量集合,因此它在某些场景中可能很有用。