80

ネストされたハッシュを使用して、配列内のデータを返す Dropbox の REST サービスからの戻り値をシミュレートするテストを作成しようとしています。

返される結果が内部に has を持つ配列であるため、Factory をコーディングする方法を理解するのに苦労しています。ここに何が入るでしょうか?

Factory.define :dropbox_hash do
 ??
end

Dropbox データは次のようになります。

 ["/home", {"revision"=>48, "rev"=>"30054214dc", "thumb_exists"=>false, "bytes"=>0, "modified"=>"Thu, 29 Dec 2011 01:53:26 +0000", "path"=>"/Home", "is_dir"=>true, "icon"=>"folder_app", "root"=>"app_folder", "size"=>"0 bytes"}] 

そして、RSpec で次のようなファクトリ コールが必要です。

Factory.create(:dropbox_hash)
4

5 に答える 5

161

私は、サードパーティ API からのコンテンツのハッシュを使用して動作する私のモデルをテストするために、同じことを行うことに興味がありました。factory_girl の組み込み機能をいくつか使用することで、この種のデータ構造をきれいに構築できることがわかりました。

これは不自然な例です:

  factory :chicken, class:Hash do
    name "Sebastian"
    colors ["white", "orange"]

    favorites {{
      "PETC" => "http://www.petc.org"
    }}

    initialize_with { attributes } 
  end

ここでの主なトリックは、initialize_with を宣言すると、factory_girl が結果のオブジェクトに属性を割り当てようとしなくなることです。この場合、db ストアもスキップするようです。したがって、複雑なものを構築する代わりに、既に準備された属性ハッシュをコンテンツとして返すだけです。出来上がり。

実際には使用されていませんが、クラスに何らかの値を指定する必要があるようです。これは、factory_girl がファクトリ名に基づいてクラスをインスタンス化しようとするのを防ぐためです。Object ではなく記述的なクラスを使用することにしましたが、それはあなた次第です。

これらのハッシュ ファクトリのいずれかを使用すると、フィールドをオーバーライドできます。

chick = FactoryGirl.build(:chicken, name:"Charles")

..ただし、ネストされたコンテンツがあり、より深いフィールドをオーバーライドしたい場合は、ある種の深いマージを行うために初期化ブロックの複雑さを増す必要があります。

あなたの場合、いくつかの混合配列とハッシュ データを使用しており、データ構造の部分間で Path プロパティを再利用する必要があるようです。問題ありません。コンテンツの構造を知っているので、結果の配列を適切に構築するファクトリを簡単に作成できます。これが私がそれを行う方法です:

  factory :dropbox_hash, class:Array do
    path "/home"
    revision 48
    rev "30054214dc"
    thumb_exists false
    bytes 0
    modified { 3.days.ago }
    is_dir true
    icon "folder_app"
    root "app_folder"
    size "0 bytes"

    initialize_with { [ attributes[:path], attributes ] }
  end

  FactoryGirl.build(:dropbox_hash, path:"/Chickens", is_dir:false)

また、不要な値を自由に省略できます。Path と rev だけが本当に必要だと想像してみましょう:

  factory :dropbox_hash, class:Array do
    path "/home"
    rev "30054214dc"
    initialize_with { [ attributes[:path], attributes ] }
  end

  FactoryGirl.build(:dropbox_hash, path:"/Chickens", revision:99, modified:Time.now)
于 2012-08-19T13:45:21.823 に答える
8

現在の RSpec バージョン (3.0) のフォローアップ:

通常どおりファクトリを定義しFactoryBot.attributes_for、インスタンス化されたクラスの代わりにハッシュを受け取るために使用します。

于 2014-07-17T12:48:01.497 に答える
6

factory_girl の最新バージョンでこれを行うことができますが、データ構造ではなくオブジェクトを構築するように設計されているため、扱いにくいです。次に例を示します。

FactoryGirl.define do
  factory :dropbox_hash, :class => 'Object' do
    ignore do
      url { "/home" }
      revision { 48 }
      rev { "30054214dc" }
      # more attributes
    end
    initialize_with { [url, { "revision" => revision, "rev" => rev, ... }] }
    to_create {}
  end
end

ここで奇妙なことを調べます:

  • すべてのファクトリには、使用されていない場合でも有効なビルド クラスが必要なので、Objectここを渡してDropboxHash.
  • ignoreのように、後で配列に割り当てようとしないように、ブロックを使用してすべての属性を無視する必要がありますarray.revision = 48
  • を使用して結果をまとめる方法を指定できますinitialize_with。ここでの欠点は、完全な属性リストを再度書き出す必要があることです。
  • 後でto_create呼び出さないように、空のブロックを提供する必要があります。array.save!
于 2012-05-03T12:28:14.620 に答える
1

私はOpenStructを使用しました:

factory :factory_hash, class:OpenStruct do
  foo "bar"
  si "flar"
end

編集:申し訳ありませんが、ハッシュとしては機能しません

最終的に静的バージョンを使用して、そのハッシュを Factory システムから取得するようにしています...

factory :factory_hash, class:Hash do
  initialize_with { {
    foo "bar"
    si "flar"
  } }
end

より良いものを探しています

于 2012-11-07T05:44:20.963 に答える