Rspec + Factory Girl First Example works, 2nd+ do not
I have an spec like so:
require 'spec_helper'
describe IncomingMailsController do
include Devise开发者_运维百科::TestHelpers
before(:each) do
@user = Factory.create(:user)
@user1 = Factory.create(:user)
@group = Factory(:group)
@perm1 = Factory.create(:permission, :user => @user)
@perm2 = Factory.create(:permission, :user => @user1)
end
it "xxxxx case 1" do
....
end
it "xxxxx case 2" do
....
end
The first case 1, works fine but then the 2nd fails with:
Failure/Error: @perm1 = Factory.create(:permission, :user => @user)
RuntimeError:
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
# ./spec/factories.rb:23
Does the before each run fresh for each it block?
factories.rb looks like:
require 'factory_girl'
Factory.define :user do |f|
f.sequence(:fname) { |n| "fname#{n}" }
f.sequence(:lname) { |n| "lname#{n}" }
f.sequence(:email) { |n| "email#{n}@google.com" }
f.password "password"
f.password_confirmation { |u| u.password }
f.invitation_code "dmbsrv82811"
end
Factory.define :group do |f|
f.name "myGroup"
f.sequence(:private_email) { |n| "myGroup#{n}" }
end
Factory.define :permission do |f|
f.role_id 1
f.group_id do
(Group.find_by_name('myGroup')).id
end
f.creator_id do
(User.find_by_fname('fname1')).id
end
end
Thanks
On line 23 of factories.rb you have
(User.find_by_fname('fname1')).id
This is hardcoded to find fname1
. However, your factory uses a sequence to define fname:
f.sequence(:fname) { |n| "fname#{n}" }
This means that in the second spec, the value for fname will be fname2, not fname1. This is because sequences aren't reset between different specs.
All of this means that when you call User.find_by_fname, it can't find a user with fname1 (only fname2), so it returns nil, which is why you get the called id for nil error.
-- Edit --
Are you doing anything with the user attribute you pass in to the permission factory (for eg with Factory.create(:permission, :user => @user)
)? If not, I'd change it to something like
Factory.create(:permission, :creator => @user)
Note: if you don't have Permission#creator setup as an association with User you'll need to rather do
Factory.create(:permission, :creator_id => @user.id)
On a similar vein, you might want to define your factory more along the lines of
Factory.define :permission do |f|
f.role_id 1
f.association :group, :factory => :group
f.association :creator, :factory => :user
end
If your associations are setup correctly, there's no need to worry about the ids, the association does the Right Thing for you.
精彩评论