2012-04-30 9 views
3

背景のClojure + Midje

私は任意の明白な誤差はご容赦くださいClojureのに新たなんだとマクロの動作を再定義。私はredis-clojureライブラリを使用するClojureデータアクセスコードをテストしようとしています。もちろん、私の統合テストは完全なスタックをテストしますが、私のユニットテストはRedisサーバーインスタンスに接続することに依存したくありません。実際のRedisコマンドをMidjeで嘲笑するのは比較的簡単ですが、接続マクロは扱いにくいです。 Midjeドキュメント経由で行うか、見つけることができないよう何

を必要

提案Redisの接続をからかったり、マクロを再定義する方法です。 core.cljから関連するトップレベルの接続マクロは次のとおりです。

(defmacro with-server 
    "Evaluates body in the context of a connection to Redis server 
    specified by server-spec. 

    server-spec is a map with any of the following keys: 
    :host  (\"127.0.0.1\") 
    :port  (6379) 
    :db  (0) 
    :timeout (5000) 
    :password (nil)" 
    ([server-spec & body] 
    `(with-connection connection# *pool* ~server-spec 
     (binding [redis.vars/*channel* (make-direct-channel connection#)] 
      [email protected])))) 

original code in context here

私は私のテストコードでマクロを再定義することができるように表示され、機能のdoesnでマクロをラップしていません私の結果を生み出すためにはまだ身体を処刑する必要があるので、私はそれ以上の進歩を得ることはできません。私が理想的にやってみたいのは、接続マクロに渡された本体を実行し、残りのマクロを破棄することです。何か案は?

+0

正確にこの問題に苦労した後、私はhttps:// githubを見つけました。com/ptaoussanis/carmine/issues/16そして、私の単体テストがローカルのredisインスタンスにヒットするのはまったく問題ないと判断しました –

答えて

1

Midje mailing listで質問をすることをお勧めします(もちろん、ここで最終回答を投稿してください)。あなたがテストしようとしていることを知らずに、アドバイスをするのは難しいです。おそらく(FreemanとPryceのGrowing Object-Oriented Software(これはClojureに当てはまります - 確かに、そのスタイルをサポートしていたのが私がMidjeを書いた理由です))、問題を2つの部分に分けたいとします。まず、Redisを分離する一連の関数を作成したいとします。これらの関数が実際のデータベースで動作する遅くて厄介な直接テストで正しく動作することをテストします。

これらの関数は、接続とラッピングマクロの必要性を隠します。

次に、Midjeの前提条件を使用して、コードが分離関数を正しく呼び出すことをテストできます。

Avdi GrimmさんのObjects on Railsは、データベースを隔離することに関して話題になる別の本です。

注:私はRedisについては何も知らないが、他のいくつかのClojure->データベースライブラリは、知的魅力的なラッピングマクロ(with-server)を使いません。代わりに、ステートフルなルートに行き、RubyデータベースライブラリのActiveRecord(暗黙的)とSequel(明示的)のように、接続を保持するグローバル変数を持っています。あまり純粋ではありませんが、それは人生(テストを含む)を簡単にするようです。 Midjeでは、その接続は、メタ定数で表すことができます。

2

多くの場合、テストのためにバインディングラッパーマクロを書きます。これらのマクロは、テストできない関数またはマクロに何かをバインドするだけです。この場合、私はこれらの行に沿って何かを書いています。

(defmacro my-fake-with-server [] 
    ....) 

(defmacro with-fake-with-server 
     (binding [redis.core/with-server my-fake-with-server] 
       (insert test here))) 

(deftest my-test (with-fake-with-server (function-that-uses-with-server))) 

これは、すべての模擬テストコードを保持します。

+0

私はこれを行うことができないようですが、 -dynamic var:redis.core/with-server " – jamiei

+0

良いアイデア。このような何かが私のためにmidjeで働いた。その問題を避けるために@jamiei、あなた自身の名前空間に別の間接参照を導入し、それを^動的に宣言し、_that_をあなたのテストの束縛でモックする –