Kamil Baćkowski
FactoryGirl.define do
factory :user do
company
end
factory :company do
subscription
end
factory :subscription do
end
factory :post do
user
end
factory :comment do
post
user
end
end
describe PostsController, type: :controller do
render_views
let(:user) { create(:user) }
let(:post) { create(:post) }
let(:comment) { create(:comment, post: post) }
describe '#show' do
it 'renders post with comments' do
post
comment
login_as user
get :show, params: { id: post.id }
# expect ...
end
end
end
How many companies, subscriptions & users ?
3 users, 3 companies and 3 subscriptions
describe PostsController, type: :controller do
render_views
let(:user) { create(:user) }
let(:post) { create(:post, user: user) }
let(:comment) { create(:comment, post: post, user: user) }
describe '#show' do
it 'renders post with comments' do
post
comment
login_as user
get :show, params: { id: post.id }
# expect ...
end
end
end
FactoryGirl.define do
factory :company do
id 1
subscription
trait :with_unlocked_id do
id nil
end
end
end
Now creating another company in spec will raise exception unless we explicitly use with_unlocked_id
create(:company)
create(:company, :with_unlocked_id)
FactoryGirl.define do
factory :comment do
post
user { post.user }
end
end
However this will only work if we have more associations, so in our case this can’t be used for post factory.
# spec/support/seed_users.rb
class SeedUsers
class << self
def load
FactoryGirl.create(:user, id: 1, :with_paid_account)
FactoryGirl.create(:user, id: 2, :with_free_account)
end
def find_with_paid_plan
User.find(1)
end
def find_with_free_plan
User.find(2)
end
end
end
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.clean
SeedUsers.load
end
describe PostsController, type: :controller do
render_views
let(:user) { SeedUsers.find_with_free_plan }
let(:post) { create(:post, user: user) }
let(:comment) { create(:comment, post: post) }
describe '#show' do
it 'renders post with comments' do
post
comment
login_as user
get :show, params: { id: post.id }
# expect ...
end
end
end
Pros
Cons
What about feature specs ? Will those work ?
Feature specs truncate tables so they will delete our seed data :(
# spec/rails_helper.rb
RSpec.configure do |config|
config.register_ordering(:global) do |items|
items.sort_by do |group|
group.metadata[:type] == :feature ? 1 : 0
end
end
end
That way feature specs will run at the end and all other specs can make use of seed data
FactoryGirl.define do
factory :post do
user
category
after(:create) do |post|
2.times { FactoryGirl.create(:comment, post: post) }
end
end
end
vs
FactoryGirl.define do
factory :post do
user
trait :with_category do
category
end
trait :with_comments do
after(:create) do |post|
2.times { FactoryGirl.create(:comment, post: post) }
end
end
end
end
Questions ?