Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Calling the syntax methods with a block yields the return object. Clo…

…ses #210
  • Loading branch information...
commit f32651d9b20173778792691bd4e04a4d0c7bc598 1 parent f4ee363
@justinko justinko authored joshuaclayton committed
View
7 GETTING_STARTED.md
@@ -69,7 +69,12 @@ factory\_girl supports several different build strategies: build, create, attrib
attrs = FactoryGirl.attributes_for(:user)
# Returns an object with all defined attributes stubbed out
- stub = FactoryGirl.build_stubbed(:user)
+ stub = FactoryGirl.build_stubbed(:user
+
+ # Passing a block to any of the methods above will yield the return object
+ FactoryGirl.create(:user) do |user|
+ user.posts.create(attributes_for(:post))
+ end
No matter which strategy is used, it's possible to override the defined attributes by passing a hash:
View
6 lib/factory_girl/factory.rb
@@ -49,7 +49,7 @@ def add_callback(name, &block)
@attribute_list.add_callback(Callback.new(name, block))
end
- def run(proxy_class, overrides) #:nodoc:
+ def run(proxy_class, overrides, &block) #:nodoc:
ensure_compiled
proxy = proxy_class.new(build_class)
callbacks.each { |callback| proxy.add_callback(callback) }
@@ -72,7 +72,9 @@ def run(proxy_class, overrides) #:nodoc:
end
end
overrides.each { |attr, val| proxy.set(attr, val) }
- proxy.result(@to_create_block)
+ result = proxy.result(@to_create_block)
+
+ block ? block.call(result) : result
end
def human_names
View
24 lib/factory_girl/syntax/methods.rb
@@ -10,12 +10,14 @@ module Methods
# The name of the factory that should be used.
# * overrides: +Hash+
# Attributes to overwrite for this set.
+ # * block:
+ # Yields the hash of attributes.
#
# Returns: +Hash+
# A set of attributes that can be used to build an instance of the class
# this factory generates.
- def attributes_for(name, overrides = {})
- FactoryGirl.factory_by_name(name).run(Proxy::AttributesFor, overrides)
+ def attributes_for(name, overrides = {}, &block)
+ FactoryGirl.factory_by_name(name).run(Proxy::AttributesFor, overrides, &block)
end
# Generates and returns an instance from this factory. Attributes can be
@@ -26,12 +28,14 @@ def attributes_for(name, overrides = {})
# The name of the factory that should be used.
# * overrides: +Hash+
# Attributes to overwrite for this instance.
+ # * block:
+ # Yields the built instance.
#
# Returns: +Object+
# An instance of the class this factory generates, with generated attributes
# assigned.
- def build(name, overrides = {})
- FactoryGirl.factory_by_name(name).run(Proxy::Build, overrides)
+ def build(name, overrides = {}, &block)
+ FactoryGirl.factory_by_name(name).run(Proxy::Build, overrides, &block)
end
# Generates, saves, and returns an instance from this factory. Attributes can
@@ -46,12 +50,14 @@ def build(name, overrides = {})
# The name of the factory that should be used.
# * overrides: +Hash+
# Attributes to overwrite for this instance.
+ # * block:
+ # Yields the created instance.
#
# Returns: +Object+
# A saved instance of the class this factory generates, with generated
# attributes assigned.
- def create(name, overrides = {})
- FactoryGirl.factory_by_name(name).run(Proxy::Create, overrides)
+ def create(name, overrides = {}, &block)
+ FactoryGirl.factory_by_name(name).run(Proxy::Create, overrides, &block)
end
# Generates and returns an object with all attributes from this factory
@@ -63,11 +69,13 @@ def create(name, overrides = {})
# The name of the factory that should be used.
# * overrides: +Hash+
# Attributes to overwrite for this instance.
+ # * block
+ # Yields the stubbed object.
#
# Returns: +Object+
# An object with generated attributes stubbed out.
- def build_stubbed(name, overrides = {})
- FactoryGirl.factory_by_name(name).run(Proxy::Stub, overrides)
+ def build_stubbed(name, overrides = {}, &block)
+ FactoryGirl.factory_by_name(name).run(Proxy::Stub, overrides, &block)
end
# Builds and returns multiple instances from this factory as an array. Attributes can be
View
17 spec/acceptance/attributes_for_spec.rb
@@ -44,3 +44,20 @@
end
end
+describe "calling `attributes_for` with a block" do
+ include FactoryGirl::Syntax::Methods
+
+ before do
+ define_model('Company', :name => :string)
+
+ FactoryGirl.define do
+ factory :company
+ end
+ end
+
+ it "passes the hash of attributes" do
+ attributes_for(:company, :name => 'thoughtbot') do |attributes|
+ attributes[:name].should eq('thoughtbot')
+ end
+ end
+end
View
17 spec/acceptance/build_spec.rb
@@ -60,5 +60,22 @@
subject.user.should be_kind_of(User)
subject.user.should be_new_record
end
+end
+
+describe "calling `build` with a block" do
+ include FactoryGirl::Syntax::Methods
+ before do
+ define_model('Company', :name => :string)
+
+ FactoryGirl.define do
+ factory :company
+ end
+ end
+
+ it "passes the built instance" do
+ build(:company, :name => 'thoughtbot') do |company|
+ company.name.should eq('thoughtbot')
+ end
+ end
end
View
18 spec/acceptance/build_stubbed_spec.rb
@@ -75,3 +75,21 @@
end
end
+describe "calling `build_stubbed` with a block" do
+ include FactoryGirl::Syntax::Methods
+
+ before do
+ define_model('Company', :name => :string)
+
+ FactoryGirl.define do
+ factory :company
+ end
+ end
+
+ it "passes the stub instance" do
+ build_stubbed(:company, :name => 'thoughtbot') do |company|
+ company.name.should eq('thoughtbot')
+ expect { company.save }.to raise_error(RuntimeError)
+ end
+ end
+end
View
18 spec/acceptance/create_spec.rb
@@ -89,3 +89,21 @@ def persisted?
FactoryGirl.create(:user).should be_persisted
end
end
+
+describe "calling `create` with a block" do
+ include FactoryGirl::Syntax::Methods
+
+ before do
+ define_model('Company', :name => :string)
+
+ FactoryGirl.define do
+ factory :company
+ end
+ end
+
+ it "passes the created instance" do
+ create(:company, :name => 'thoughtbot') do |company|
+ company.name.should eq('thoughtbot')
+ end
+ end
+end

4 comments on commit f32651d

@yfeldblum

The specs should also verify that the block was called.

If the block does not get called then the expectation will never be declared because the expectation is declared inside the block. Therefore there should be a separate set specifications that expect the block to be called in the first place.

it "calls the block" do
  block = proc { nil }
  block.should_receive(:call)
  create(:company, :name => 'thoughtbot', &block)
end

This applies to each of #create, #build, #stub, and #attributes_for.

@joshuaclayton

@yfeldblum the tests do test that the block is called. That's what's allowing the testing of attributes on company in this spec, for example:

create(:company, :name => 'thoughtbot') do |company|
  company.name.should eq('thoughtbot')
end
@joshuaclayton

Nevermind, I see what you're saying now, good catch.

@joshuaclayton

Commit: 4ede9f1

Please sign in to comment.
Something went wrong with that request. Please try again.