1. ホーム
  2. ruby-on-rails-3

[解決済み] factory_botで配列/ハッシュを定義するには?

2023-08-03 07:27:56

質問

Dropbox の REST サービスからの戻り値をシミュレートするテストを書こうとしていますが、これはネストされたハッシュを持つ Array のデータを私に返します。

戻り値は内部にハッシュを持つ配列であるため、私のファクトリーをどのようにコード化するかについて困っています。 ここに何が入るのでしょうか?

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)

どのように解決するのですか?

私は同じことをすることに興味があり、また、サードパーティ 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ではなく、説明的なクラスを使用することにしましたが、それはあなた次第です。

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

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)