Created
August 9, 2011 23:00
-
-
Save dandorman/1135434 to your computer and use it in GitHub Desktop.
FactoryGirl vs. Fabrication
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
describe FeaturePool do | |
it "creates a new instance given valid attributes" do | |
Fabricate :feature_pool | |
end | |
it "is not valid without a name" do | |
Fabricate.build(:feature_pool, :name => "").should_not be_valid | |
end | |
describe "#current" do | |
it "returns the feature appearance whose position corresponds with #head" do | |
pool = Fabricate :populated_feature_pool | |
pool.current.featurable.user.name.should == "John Gruber" | |
end | |
it "has some feature appearances" do | |
pool = Fabricate :populated_feature_pool | |
pool.should have(5).feature_appearances | |
end | |
it "persists its appearances" do | |
Fabricate :populated_feature_pool, :name => "foo/bar" | |
pool = FeaturePool.find_by_name("foo/bar") | |
pool.should have(5).feature_appearances | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Fabricator(:feature_pool) do | |
name "home/primary" | |
accepts "NewsArticle" | |
rotate_after 24 | |
head 1 | |
paused false | |
end | |
Fabricator(:populated_feature_pool, :from => :feature_pool) do | |
feature_appearances!(:count => 5) do |feature_pool, position| | |
Fabricate :feature_appearance, :feature_pool => feature_pool, :position => position | |
end | |
end | |
Fabricator(:feature_appearance) do | |
featurable! :fabricator => :news_article | |
position 1 | |
end | |
Fabricator(:news_article) do | |
title "This Is the New Apple" | |
body "Superior products _and_ mainstream prices." | |
user! | |
end | |
Fabricator(:user) do | |
name "John Gruber" | |
email { sequence(:email) {|n| "user#{n}@example.com" } } | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FactoryGirl.define do | |
factory :feature_pool do | |
name "home/primary" | |
accepts "NewsArticle" | |
rotate_after 24 | |
head 1 | |
paused false | |
factory :populated_feature_pool do | |
feature_appearances { FactoryGirl.build_list(:feature_appearance, 5) } | |
end | |
end | |
factory :feature_appearance do | |
association :featurable, :factory => :news_article | |
position 1 | |
end | |
factory :news_article do | |
title "This Is the New Apple" | |
body "Superior products _and_ mainstream prices." | |
user | |
end | |
factory :user do | |
name "John Gruber" | |
sequence(:email) {|n| "user#{n}@example.com" } | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
describe FeaturePool do | |
it "creates a new instance given valid attributes" do | |
FactoryGirl.create(:feature_pool) | |
end | |
it "is not valid without a name" do | |
FactoryGirl.build(:feature_pool, :name => "").should_not be_valid | |
end | |
describe "#current" do | |
it "returns the feature appearance whose position corresponds with #head" do | |
pool = FactoryGirl.create(:populated_feature_pool) | |
pool.current.featurable.user.name.should == "John Gruber" | |
end | |
it "has some feature appearances" do | |
pool = FactoryGirl.create(:populated_feature_pool) | |
pool.should have(5).feature_appearances | |
end | |
it "persists its appearances" do | |
FactoryGirl.create(:populated_feature_pool, :name => "foo/bar") | |
pool = FeaturePool.find_by_name("foo/bar") | |
pool.should have(5).feature_appearances | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
These examples display pretty bad practices unfortunately - you should never build up complex structure in your factories or fabrications. It gives them the same downsides as fixtures. Structure should always be built up within the test itself.
Having complex structure in factory objects to DRY your tests obscures the object structure, adds unnecessary associations for tests that don't use them, and creates problems when you need a test which changes one small association or value, and all your other tests fail. It's an example of bad DRY.
Sucks that people keep persisting it. The line:
pool.should have(5).feature_appearances
...for example, means that your test is now tied to 5 associated objects within EVERY feature pool factory by default - unseen by the test itself. All tests that don't need any feature appearances, create them anyway. Then you start building tests assuming the value will be five, overriding if not - suddenly most of your tests are overwriting the default, somebody changes it, and your tests are breaking because of a value far outside the test itself.
Obviously this is an overly simplified example that is easy to fix, but start multiplying the assumptions you're making about the structure of your data, with other associations and sub-objects, and soon your tests are unmaintainable soup.