我对做同样的事情感兴趣,还想测试我的模型,该模型使用第3方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尝试根据工厂名称实例化类。我选择使用描述性类而不是对象,但这取决于您。
使用以下哈希工厂之一时,您仍然可以覆盖字段:
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)