我有兴趣做同样的事情,也想测试我的一个模型,该模型使用来自 3rd-party 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)
您仍然可以随意省略不必要的值。让我们假设只有 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)