FactoryGirl在工厂中更改属性结构

时间:2015-11-03 17:40:42

标签: ruby-on-rails factory-bot

FactoryGirl 4.5.0

如何更改传递属性的结构?例如,在处理大量现有测试时,在序列化现有字段时,工厂最好使用旧属性来制作新模型。

说明

鉴于模型Emerald:

# app/models/emerald.rb
class Emerald < ActiveRecord::Base
  validates_presence_of :name, :size, :shinyness, :color
end

Emerald的工厂:

# spec/factories/emerald_spec.rb
FactoryGirl.define do
  factory :emerald do
    sequence(:name) {|n| "Emerald #{n} name"}
    size: 12
    shinyness: 34
    color: 'Dark Green'
  end
end

许多rspec测试都做了类似的事情:

let(:shiny_emerald) { create(:emerald, attributes: { name: 'Shiny', shinyness: 99 })}
let(:big_emerald)   { create(:emerald, attributes: { name: 'Big', size: 888 })}

当序列化Emerald中的某些字段时,我们得到了

# app/models/emerald.rb
class Emerald < ActiveRecord::Base

  serialize :emerald_properties, Hash

  validates_presence_of :name
  validates :emerald_properties, emerald_properties: true # This is a custom validator

  def size
    emerald_properties[:size]
  end
  def size=(value)
    emerald_properties[:size] = value
  end
  def shinyness
    emerald_properties[:shinyness]
  end
  def shinyness=(value)
    emerald_properties[:shinyness] = value
  end
  def colour
    emerald_properties[:colour]
  end
  def colour=(value)
    emerald_properties[:colour] = value
  end
end

&#34;为什么不要* 以不同的方式进行此操作,这可能在本示例的有限范围内,但不适用于任何可能搜索此*的人&#34;除此之外,在工厂应该做些什么来让现有的测试保持不变?

该模型仍允许您emerald.size而不是强制使用emerald.emerald_properties[:size],我的目标是为了挥舞工厂而实现同样的目标。

要做很多工作:

let(:big_emerald) { create(:emerald, attributes: { name: 'Big', emerald_properties{ size: 888 }})}

无处不在,旨在保持

let(:big_emerald) { create(:emerald, attributes: { name: 'Big', size: 888 })}

并在工厂内进行调整。

到目前为止,我有:

FactoryGirl.define do
  factory :emerald do
    sequence(:name) {|n| "Emerald #{n} name"}
    emerald_properties ({ {size: 12, shinyness: 34, color: 'Dark Green'}.merge(attributes.slice(*[:size, :shinyness, :color])) })
  end
end

但它不起作用

1 个答案:

答案 0 :(得分:0)

它只需要双重支架&#39;不做内联时。

How to define an array / hash in Factory Girl?

的误解
# valid
favorites {{
  "PETC" => "http://www.petc.org"
}}
# invalid
favorites {
  "PETC" => "http://www.petc.org"
}
# invalid
favorites {{ "PETC" => "http://www.petc.org" }}
# valid
favorites { "PETC" => "http://www.petc.org" }

因此解决方案在删除未使用的大括号后起作用:

FactoryGirl.define do
  factory :emerald do
    sequence(:name) {|n| "Emerald #{n} name"}
    emerald_properties { {size: 12, shinyness: 34, color: 'Dark Green'}.merge(attributes.slice(*[:size, :shinyness, :color])) }
  end
end

也是不必要的{},而不是()