1
0
Fork 0
mirror of https://github.com/thoughtbot/factory_bot.git synced 2022-11-09 11:43:51 -05:00
thoughtbot--factory_bot/spec/acceptance/initialize_with_spec.rb
Joshua Clayton a5b3a97c9d Optionally disable duplicate assignment of attributes in initialize_with
By setting:

    FactoryGirl.duplicate_attribute_assignment_from_initialize_with =
false

This turns off duplicate assignment of attributes accessed from
initialize_with. This means any attributes accessed from the factory and
assigned in the initialize_with block won't be subsequently set after
the object has been instantiated.

This will be the default functionality in 4.0.

Closes #345
2012-05-18 17:38:23 -04:00

220 lines
4.7 KiB
Ruby

require "spec_helper"
describe "initialize_with with non-FG attributes" do
include FactoryGirl::Syntax::Methods
before do
ActiveSupport::Deprecation.silenced = true
define_model("User", name: :string, age: :integer) do
def self.construct(name, age)
new(name: name, age: age)
end
end
FactoryGirl.define do
factory :user do
initialize_with { User.construct("John Doe", 21) }
end
end
end
subject { build(:user) }
its(:name) { should == "John Doe" }
its(:age) { should == 21 }
end
describe "initialize_with with FG attributes that are ignored" do
include FactoryGirl::Syntax::Methods
before do
ActiveSupport::Deprecation.silenced = true
define_model("User", name: :string) do
def self.construct(name)
new(name: "#{name} from .construct")
end
end
FactoryGirl.define do
factory :user do
ignore do
name { "Handsome Chap" }
end
initialize_with { User.construct(name) }
end
end
end
subject { build(:user) }
its(:name) { should == "Handsome Chap from .construct" }
end
describe "initialize_with with FG attributes that are not ignored" do
include FactoryGirl::Syntax::Methods
before do
ActiveSupport::Deprecation.silenced = true
define_model("User", name: :string) do
def self.construct(name)
new(name: "#{name} from .construct")
end
end
FactoryGirl.define do
factory :user do
name { "Handsome Chap" }
initialize_with { User.construct(name) }
end
end
end
it "assigns each attribute even if the attribute has been used in the constructor" do
build(:user).name.should == "Handsome Chap"
end
end
describe "initialize_with non-ORM-backed objects" do
include FactoryGirl::Syntax::Methods
before do
ActiveSupport::Deprecation.silenced = true
define_class("ReportGenerator") do
attr_reader :name, :data
def initialize(name, data)
@name = name
@data = data
end
end
FactoryGirl.define do
sequence(:random_data) { 5.times.map { Kernel.rand(200) } }
factory :report_generator do
ignore do
name "My Awesome Report"
end
initialize_with { ReportGenerator.new(name, FactoryGirl.generate(:random_data)) }
end
end
end
it "allows for overrides" do
build(:report_generator, name: "Overridden").name.should == "Overridden"
end
it "generates random data" do
build(:report_generator).data.length.should == 5
end
end
describe "initialize_with parent and child factories" do
before do
ActiveSupport::Deprecation.silenced = true
define_class("Awesome") do
attr_reader :name
def initialize(name)
@name = name
end
end
FactoryGirl.define do
factory :awesome do
ignore do
name "Great"
end
initialize_with { Awesome.new(name) }
factory :sub_awesome do
ignore do
name "Sub"
end
end
factory :super_awesome do
initialize_with { Awesome.new("Super") }
end
end
end
end
it "uses the parent's constructor when the child factory doesn't assign it" do
FactoryGirl.build(:sub_awesome).name.should == "Sub"
end
it "allows child factories to override initialize_with" do
FactoryGirl.build(:super_awesome).name.should == "Super"
end
end
describe "initialize_with implicit constructor" do
before do
ActiveSupport::Deprecation.silenced = true
define_class("Awesome") do
attr_reader :name
def initialize(name)
@name = name
end
end
FactoryGirl.define do
factory :awesome do
ignore do
name "Great"
end
initialize_with { new(name) }
end
end
end
it "instantiates the correct object" do
FactoryGirl.build(:awesome, name: "Awesome name").name.should == "Awesome name"
end
end
describe "initialize_with doesn't duplicate assignment on attributes accessed from initialize_with" do
before do
ActiveSupport::Deprecation.silenced = true
define_class("User") do
attr_reader :name
attr_accessor :email
def initialize(name)
@name = name
end
end
FactoryGirl.define do
sequence(:email) {|n| "person#{n}@example.com" }
factory :user do
email
name { email.gsub(/\@.+/, "") }
initialize_with { new(name) }
end
end
end
it "instantiates the correct object" do
FactoryGirl.duplicate_attribute_assignment_from_initialize_with = false
built_user = FactoryGirl.build(:user)
built_user.name.should == "person1"
built_user.email.should == "person1@example.com"
end
end