我对做同样的事情很感兴趣,也是为了测试我使用第三方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将不再尝试将属性分配给结果对象。它似乎也跳过了数据库存储。因此,我们不需要构建任何复杂的内容,只需将已准备好的属性哈希作为我们的内容返回即可。大功告成。
似乎需要指定一些类的值,尽管实际上没有使用该类。这是为了防止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)
您仍然可以省略不必要的值。假设只有路径和版本是真正必需的:
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)