5

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

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

在 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。

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

当然,在我的真实代码库中,我必须对所有协议和 defrecords 执行此操作,因此非常繁琐且耗时。此外,如果我只是简单地放入一个 shell 并执行lein test,我会得到相同的 ClassNotFoundException。

有没有更好的办法?

感谢您的时间和帮助。

4

2 回答 2

4

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

(:import [foo.types RequestProcessor]))不能单独工作,因为这只适用于类路径中已经存在的 Java 类。这不是这里的情况,因为您使用 defrecord 在运行时动态创建类。

import通常只需要 Java 互操作。

于 2013-01-17T10:04:36.073 回答
2

defrecord在运行时动态生成类。一旦你进入命名空间并运行代码,类就会出现并且测试正常加载,因为类现在存在。如果您use在测试中使用命名空间除了importing 类之外,它是否为您正确加载?

于 2013-01-16T19:48:26.497 回答