Unit testing Can';当结果是一个函数时,t将test设置为true(在…处编译时出现语法错误,没有这样的变量:…)

Unit testing Can';当结果是一个函数时,t将test设置为true(在…处编译时出现语法错误,没有这样的变量:…),unit-testing,testing,clojure,clojurescript,clojure.test,Unit Testing,Testing,Clojure,Clojurescript,Clojure.test,当我想测试结果是另一个函数的函数时发生。 我有这样的想法: ns flexsearch.core (defn init [{:keys [tokenizer split indexer filter] :as options}] (let [encoder (get-encoder (:encoder options))] (assoc (merge {:ids {} :data {}} options) :indexer (get-indexer index

当我想测试结果是另一个函数的函数时发生。 我有这样的想法:

ns flexsearch.core

(defn init [{:keys [tokenizer split indexer filter] :as options}]
  (let [encoder (get-encoder (:encoder options))]
    (assoc (merge {:ids {} :data {}} options)
           :indexer (get-indexer indexer)
           :encoder encoder
           :tokenizer (if (fn? tokenizer) tokenizer #(string/split % (or split #"\W+")))
           :filter (set (mapv encoder filter)))))
在测试ns中:

ns flexsearch.core-test
[flexsearch.core :as f]

(def split #"\W+")

(is (= (f/init {:tokenizer false :split split :indexer :forward :filter #{"and" "or"}})
         {:ids {},
          :data {},
          :tokenizer f/init/fn--14976,
          :split #"\W+",
          :indexer f/index-forward,
          :filter #{"or" "and"},
          :encoder f/encoder-icase}))
repl中的结果是:

{:ids {},
 :data {},
 :tokenizer #function[flexsearch.core/init/fn--14976],
 :split #"\W+",
 :indexer #function[flexsearch.core/index-forward],
 :filter #{"or" "and"},
 :encoder #function[flexsearch.core/encoder-icase]}
我知道我必须提出f/index,而不是repl[flexsearch.core/index forward]的结果,但它不适用于f/init/fn--14976(没有这样的变量:f/init/fn--14976)

我相信这是一个骗局,但我不知道它到底是如何运作的。你能提供的任何阅读资料我都将不胜感激

---编辑--- f/索引转发和f/编码器icase符号工作正常

---编辑2--- 我定义了:

(defn spliter [split]   (fn [x] (string/split x (or split #"\W+"))))
并将其用于:

(defn init [{:keys [tokenizer split indexer filter] :as options}]
  (let [encoder (get-encoder (:encoder options))]
    (assoc (merge {:ids {} :data {}} options)
           :indexer (get-indexer indexer)
           :encoder encoder
           :tokenizer (if (fn? tokenizer) tokenizer (spliter split))
           :filter (set (mapv encoder filter)))))

我得到了一个类似的“:tokenizer#function[flexsearch.core/spliter/fn--34857]”,我在测试中使用了它,但它也失败了–

Ithink“No-soke-var”错误正在发生,因为tokenizer是一个匿名函数

如果您在
flexsearch.core
中将默认标记器定义为非匿名函数,然后在测试中使用该名称,那么它就可以工作了


然而,一般来说,你不能比较两个函数是否相等——正如@cfrick所说。当您在比较映射时,其中一些值是函数,您仍然在比较函数。

为什么要测试函数是否相等?嗯,我正在测试映射是否相等(函数作为值),如果我没有错,那么“不能”是什么意思?我不应该那样做还是我不能?因为(=++)确实是真的。。。。对不起,如果我的问题很愚蠢,你不能。你可以比较身份,但不能比较平等。您的
(=++)
示例是身份检查。但是下面是一个等式检查
(=(fn[xy](+xy))(fn[xy](+xy)))
。总的来说,函数相等是一个无法确定的问题。不知何故,我的评论只涉及了部分内容。那么,剩下的就是。。。。在您编辑的示例中,每次调用
(splitter split)
都会返回一个不同的函数。至于您最初的错误(“没有这样的变量”),在REPL中,您看到的
#函数[flexsearch.core/init/fn--14976]
就是匿名函数(一个不绑定到任何名称的函数)的打印方式
flexsearch.core/init/fn--14976
不是函数绑定到的名称(即符号)。因此,当您在测试中指定
flexsearch.core/init/fn--14976
时,系统没有找到绑定到该符号的任何变量,因此会发出抱怨。具体来说,当Clojure计算一个符号时,它会在名称空间中查找该符号(基本上是从符号到变量的映射)。查找的结果应该是一个var。然后Clojure获取var的内容并将其用作评估的结果。下面的内容可能会有所帮助,尤其是以“除符号和列表外,大多数文字Clojure形式都会自行评估”开头的段落。