5

私のClojureコードベースでは、いくつかのプロトコルといくつかのdefrecordを定義しました。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内でClojure1.4、Leiningen 2、nreplを使用しています。

私が直面している厄介な点は、単体テストを実行しようとすると(たとえば、Cc C-、シーケンスを使用して)、ClassNotFoundException:foo.types.RequestProcessorが発生することです。これを回避するために、プロトコルとdefrecordフォームのそれぞれを個別に評価する手動作業を行っています。つまり、protocols.cljに移動して、defprotocolフォームを評価します(nreplのCMxキーシーケンス)。次に、types.cljに移動して、defrecordフォームを評価します。そして最後に、ClassNotFoundExceptionを取得せずに単体テストを正常に実行できるようになりました。

もちろん、私の実際のコードベースでは、すべてのプロトコルとdefrecordに対してこれを実行する必要があるため、非常に面倒で時間がかかります。また、単にシェルにドロップしてラインテストを実行すると、同じClassNotFoundExceptionが発生します。

もっと良い方法はありますか?

お手数をおかけしますが、よろしくお願いいたします。

4

2 に答える 2

4

requireテスト名前空間にdefrecordを含む名前空間が必要です。

(:import [foo.types RequestProcessor]))クラスパスにすでに存在するJavaクラスに対してのみ機能するため、単独では機能しません。実行時にdefrecordを使用してクラスを動的に作成しているため、これはここでは当てはまりません。

import通常、Java相互運用にのみ必要です。

于 2013-01-17T10:04:36.073 に答える
2

defrecordは、実行時にクラスを動的に生成します。名前空間に移動してコードを実行すると、クラスが作成され、クラスが存在するため、テストが正常に読み込まれます。useクラスに加えてテスト内から名前空間を使用する場合、名前空間はimport適切に読み込まれますか?

于 2013-01-16T19:48:26.497 に答える