The ease and fidelity of factories with the performance of static fixtures.
Prefactory allows you to create factory objects and perform other expensive ActiveRecord operations in RSpec before(:all) blocks, transparently wrapping example groups in nested transactions to automatically roll back any data changes that occur during a specific test, while also ensuring after-commit callbacks are executed for the synthetic commits.
- ActiveRecord >= 4
- RSpec
- FactoryGirl
- A database for which ActiveRecord supports nested transactions (e.g. MySQL, Postgresql)
Add the gem to the :test group in your Rails application's Gemfile:
group :test do
gem 'prefactory'
end
Add this to your RSpec spec_helper.rb
RSpec.configure do |config|
config.include Prefactory
# ensure Rails' transaction fixtures are disabled
config.use_transactional_fixtures = false
# optional, to enable shorthand creation
# using only Factory name (see examples, below)
config.include FactoryGirl::Syntax::Methods
end
describe User do
before :all do # executes once
# invokes FactoryGirl.create(:user)
# reference object as 'friend' in tests
prefactory_add(:friend) { FactoryGirl.create :user }
# invokes create(:user) if available, e.g
# if rspec is configured with:
# config.include FactoryGirl::Syntax::Methods
# reference object as 'user' in examples
prefactory_add :user
end
# convenience method, equivalent to:
# before(:all) do
# prefactory_add(:other_friend) do
# create :user
# end
# end
set!(:other_friend) { create :user }
context 'a new user' do
it { expect(user.friends.count).to eq 0 }
context 'with a friend' do
before(:all) { user.add_friend(friend) } # executes once
it { expect(user.friends.count).to eq 1 }
# these changes will be transparently rolled back
it "allows removing the friend" do
expect { user.remove_friend(friend) }.to_not raise_error
expect(user.friends.count).to eq 0
end
it "disallows adding the same friend again" do
expect { user.add_friend(friend) }.to raise_error
expect(user.friends.count).to eq 1
end
# these changes will be transparently rolled back
it "allows adding a different friend" do
expect { user.add_friend(other_friend) }.to_not raise_error
expect(user.friends.count).to eq 2
end
it { expect(user.friends).to include friend }
it { expect(user.friends).not_to include other_friend }
end
end
end
See also: An example rails application with Prefactory configured
- Fork it ( http://github.com/socialcast/prefactory/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a pull request
Copyright (c) 2012-2014 VMware, Inc. All Rights Reserved. Released under the terms of the MIT license. See LICENSE for details.