clojure - 在 Clojure 中进行单元测试时,如何避免手动评估 defrecords 和 defprotocols?

标签 clojure

在我的 Clojure 代码库中,我定义了几个协议(protocol)和几个 defrecord。我正在使用 clojure.test 对我的 defrecord 中定义的具体函数进行单元测试。

例如,假设我有以下源文件:

在 src/foo/protocols.clj 中:

(ns foo.protocols)

(defprotocol RequestAcceptability
  (desired-accepted-charset [this]))

在 src/foo/types.clj 中:

(ns foo.types
  (:use [foo.protocols :only [RequestAcceptability desired-accepted-charset]])

(defrecord RequestProcessor
  [field-1 field-2]
  RequestAcceptability
  (desired-accepted-charset [this]
    ...implementation here...))

在 test/foo/types_test.clj 中:

(ns foo.types-test
  (:use [clojure.test])
  (:use [foo.protocols :only [RequestAcceptability desired-accepted-charset]])
  (:import [foo.types RequestProcessor]))

(deftest test-desired-accepted-charset_1
  ...test code here...)

我在 Emacs 中使用 Clojure 1.4、Leiningen 2、nrepl。

我面临的烦恼是,当我去运行单元测试时(例如,使用 C-c C-, 序列),我得到一个 ClassNotFoundException: foo.types.RequestProcessor。为了解决这个问题,我正在手动评估每个协议(protocol)和 defrecord 表单。即,我将导航到protocols.clj并评估(nrepl的C-M-x键序列)我的defprotocol表单;然后我将导航到 types.clj 并评估我的 defrecord 表单;最后我能够成功运行我的单元测试,而不会出现 ClassNotFoundException。

当然,在我的真实代码库中,我必须对所有协议(protocol)和 defrecord 执行此操作,因此这是非常乏味且耗时的。另外,如果我只是进入 shell 并执行 lein test,我会得到相同的 ClassNotFoundException。

有更好的方法吗?

感谢您的时间和帮助。

最佳答案

您需要require测试命名空间中包含defrecord的命名空间。

(:import [foo.types RequestProcessor])) 本身不起作用,因为它仅适用于类路径中已存在的 Java 类。此处的情况并非如此,因为您正在使用 defrecord 在运行时动态创建该类。

import 通常仅用于 Java 互操作。

关于clojure - 在 Clojure 中进行单元测试时,如何避免手动评估 defrecords 和 defprotocols?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14363216/

相关文章:

java - ImageIO 导入不起作用 Clojure

clojure - 如何从防火墙后面安装 Leiningen 自安装?

用于特定查询的 jdbc getMetaData

clojure - 如何最好地关闭Clojure Core.Async进程管道

Clojure - 返回闭包或部分应用函数更惯用?

clojure - 为什么在 "use"(在 clojure 中)中的向量周围使用单引号?

clojure - 在与 Clojure 中运行代码相同的目录中打开文件

java - Clojure 宏实例化异常

clojure - 在 leiningen 中定义项目特定任务

clojure - 莱宁根编译顺序?