14

クラスがオープンであるため、Ruby は DI や DI フレームワークを実際には必要としないという記事を読んだことを覚えています。その結果、依存関係のコンストラクターを簡単に書き直して、偽のオブジェクトを返すことができます。

私はClojureと関数型プログラミングに非常に慣れていません。Clojure に依存性注入が必要なのか、それとも同様の理由またはその他の理由でそれを差し控えることができるのか疑問に思っています。以下は具体的な作業例です (私の設計が Clojure の慣用句ではないことを指摘してください):

Web クローラー/スパイダーを開発していると想像してください。ダウンロードした Web ページをトラバースする必要があります。これは副作用のあるアクションです。クエリごとに Web ページが変更されたり、インターネット接続が切断されたりする可能性があります。Web ページ上のすべてのリンクを見つけて、それぞれにアクセスし、同じ方法でトラバースします。

ここで、代わりにハードコードされた文字列応答を返すように、http クライアントをモック アウトするテストを作成します。-mainテストでプログラムを呼び出して、実際のhttp クライアントを使用しないようにするにはどうすればよいですか?

4

3 に答える 3

17

with-redefsclojure.coreのマクロは、関数をスタブ化するのに非常に便利です。

これを示す短い REPL セッションを次に示します。

user=> (defn crawl [url]
  #_=>   ;; would now make http connection and download content
  #_=>   "data from the cloud")
#'user/crawl
user=> (defn -main [& args]
  #_=>   (crawl "http://www.google.com"))
#'user/-main
user=> (-main)
"data from the cloud"
user=> (with-redefs [crawl (fn [url] "fake data")]
  #_=>   (-main))
"fake data"

Clojure プログラムは (大部分) オブジェクトではなく関数で構成されているため、関数の動的な再バインドは、DI フレームワークがテスト目的で行うことのかなりの部分を置き換えます。

于 2013-03-29T04:25:37.423 に答える
11

Clojure では通常、別の方法で依存性注入と同等のことを実現します。

  • 動的バインディング- たとえば、テスト関数で標準出力をリダイレクトするのに役立ちます。(binding [*out* some-writer-object] ...)
  • 高階関数- 他の関数をパラメーターとして渡すことにより、依存性注入の形式を提供するために使用できます
  • データを使用した構成- Clojure では、構成パラメーター (またはカスタム動作を構成する関数) を含むマップを渡すことはかなり慣用的です。

これらはすべて、言語自体に不可欠です。したがって、「DIフレームワーク」のようなものは絶対に必要ありません。私見ですが、DI のフレームワークが必要なのは、言語自体に十分な機能がないことを補っているだけです。

于 2013-03-29T03:41:30.760 に答える
3

Web クローラー/スパイダーを開発していると想像してください。ダウンロードした Web ページをトラバースする必要があります。これは副作用のあるアクションです。クエリごとに Web ページが変更されたり、インターネット接続が切断されたりする可能性があります。Web ページ上のすべてのリンクを見つけて、それぞれにアクセスし、同じ方法でトラバースします。

ここでは、依存性注入の必要はないと思います。テスト容易性を維持しながら、この問題に取り組む方法を次に示します。実装を最低 2 つの関数に分割します。1 つの関数は Web ページを取得して返し、もう 1 つの関数は応答を解析します。メイン関数には、次のようなものがあり(-> "http://google.com" fetch parse)ます。

次に、テストparseするには、メソッドをバイパスして、fetch偽の Web ページ データをメソッドに直接フィードしparseます。

(deftest test
     (is (= {:something "blah"} (parse "<html><head><title>Fake webpage etc..</title></head></html>"))))

問題を明確な関数に分解することに注意している限り、DI のような洗練されたものをテストする必要はないと思います。

私は Clojure を初めて使用するので、ここで他の人が言及しているマクロや手法には詳しくありませんが、上記の方法論はこれまでのところうまく機能しています。

于 2013-03-29T18:25:41.823 に答える