如何在 factory_bot 中定义数组/哈希? [英] How to define an array / hash in factory_bot?

查看:12
本文介绍了如何在 factory_bot 中定义数组/哈希?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个测试来模拟 Dropbox 的 REST 服务的一些返回值,该服务以数组形式返回数据,并带有嵌套的散列.

I am trying to write a test that simulates some return values from Dropbox's REST service that gives me back data in an Array, with a nested hash.

我在弄清楚如何对我的工厂进行编码时遇到了麻烦,因为返回结果是一个内部有 has 的数组.什么会去这里?

I am having trouble figuring out how to code my Factory since the return result is an array with a has inside. What would go here?

Factory.define :dropbox_hash do
 ??
end

Dropbox 数据如下所示:

Dropbox data looks like this:

 ["/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 中进行这样的工厂调用:

And I'd like a factory call like this in my RSpec:

Factory.create(:dropbox_hash)

推荐答案

我对做同样的事情很感兴趣,还想测试我的模型,该模型使用来自 3rd 方 API 的内容散列进行操作.我发现通过使用 factory_girl 的一些内置功能,我能够干净地构建此类数据结构.

I was interested in doing the same thing, also to test a model of mine that operates using a hash of content from a 3rd-party API. I found that by using a few of the built-in features of factory_girl I was able to cleanly construct these sort of data structures.

这是一个人为的例子:

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

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

    initialize_with { attributes } 
  end

这里的主要技巧是,当您声明 initialize_with 时, factory_girl 将不再尝试将属性分配给结果对象.在这种情况下,它似乎也跳过了数据库存储.因此,与其构造任何复杂的东西,我们只需将已经准备好的属性哈希作为我们的内容传回.瞧.

The main trick here is that when you declare initialize_with, factory_girl will no longer attempt to assign the attributes to the resultant object. It also seems to skip the db store in this case. So, instead of constructing anything complicated, we just pass back the already prepared attribute hash as our content. Voila.

尽管实际上并没有使用它,但似乎确实有必要为该类指定一些值.这是为了防止 factory_girl 尝试根据工厂名称实例化类.我选择使用描述性类而不是对象,但这取决于您.

It does seem necessary to specify some value for the class, despite it not actually being used. This is to prevent factory_girl from attempting to instantiate a class based on the factory name. I've chosen to use descriptive classes rather than Object, but it's up to you.

当您使用以下哈希工厂之一时,您仍然可以覆盖字段:

You're still able to override fields when you use one of these hash factories:

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

..但是,如果您有嵌套内容并想要覆盖更深的字段,您将需要增加初始化块的复杂性以进行某种深度合并.

..however, if you have nested content and want to override deeper fields you will need to increase the complexity of the initialization block to do some sort of deep merge.

在您的情况下,您使用的是一些混合数组和散列数据,看起来应该在数据结构的各个部分之间重用 Path 属性.没问题 - 您知道内容的结构,因此您可以轻松创建一个正确构造结果数组的工厂.我可以这样做:

In your case, you're using some mixed array and hash data, and it appears that the Path property should be reused between portions of the data structure. No problem - you know the structure of the content, so you can easy create a factory that constructs the resulting array properly. Here's how I might do it:

  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 才是真正需要的:

You are also still free to omit unnecessary values. Let's imagine only Path and rev are really necessary:

  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)

这篇关于如何在 factory_bot 中定义数组/哈希?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆