lein 测试使用 "resolve" 为函数抛出 NPE;在 REPL 工作

lein test throws NPE for function using "resolve"; works in REPL

lein test 在测试使用 (resolve (symbol "a-fn")) 到 return 函数 a-fn 的函数时抛出 NullPointerException。测试在 REPL 中运行良好。

我无法在 leiningen 的测试套件中找到解决 a-fn 的方法,如果那确实是问题的话。

我通过 lein new my-resolve 创建了一个名为 my-resolve 的 Leiningen 项目,并为它们添加了两个函数和测试:

src/my_resolve/core.clj:

(ns my-resolve.core)

(defn a-fn [] "From a-fn")

(defn my-resolve [] (resolve (symbol "a-fn")))

test/my_resolve/core_test.clj:

(ns my-resolve.core-test
  (:require [clojure.test :refer :all]
            [my-resolve.core :refer :all]))

;; Passes
(deftest a-fn-test
  (testing "a-fn"
    (is (= (a-fn)
           "From a-fn"))))

;; my-resolve-test behaves correctly in the REPL (the test passes,
;; returns nil) but throws a NullPointerException when called from
;; lein test.
(deftest my-resolve-test
  (testing "my-resolve"
    (is (= ((my-resolve))
           "From a-fn"))))

谢谢。

resolve 使用动态绑定 *ns* 委托给 ns-resolve,这在 my-resolve.core/my-resolve 中的调用点会有所不同,具体取决于它所在的命名空间来自:

user=> (doc resolve)
-------------------------
clojure.core/resolve
([sym] [env sym])
  same as (ns-resolve *ns* symbol) or (ns-resolve *ns* &env symbol)

我假设在 REPL 中你在 my-resolve.core ns 中调用 my-resolve。当 lein testmy-resolve.core-test 中执行测试时,*ns* 动态绑定到 (the-ns 'user) 并且 ns(很可能)不包含对 my-resolve 的绑定。