AnA*_*ice 2 rspec ruby-on-rails rspec2 ruby-on-rails-3 factory-bot
我有一个这样的规格:
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
Run Code Online (Sandbox Code Playgroud)
第一个案例1,工作正常,但第二个案例失败:
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
Run Code Online (Sandbox Code Playgroud)
每个块之前每次运行都是新鲜的吗?
factories.rb看起来像:
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
Run Code Online (Sandbox Code Playgroud)
谢谢
在factory.rb的第23行你有
(User.find_by_fname('fname1')).id
Run Code Online (Sandbox Code Playgroud)
这是硬编码找到的fname1.但是,您的工厂使用序列来定义fname:
f.sequence(:fname) { |n| "fname#{n}" }
Run Code Online (Sandbox Code Playgroud)
这意味着在第二个规范中,fname的值将是fname2,而不是fname1.这是因为序列不会在不同规格之间重置.
所有这一切都意味着,当你调用User.find_by_fname,它无法找到fname1(仅fname2)的用户,所以它返回nil,这就是为什么你会得到零误差的名为id.
- 编辑 -
您是否正在使用传递给权限工厂的用户属性执行任何操作(例如Factory.create(:permission, :user => @user))?如果没有,我会把它改成类似的东西
Factory.create(:permission, :creator => @user)
Run Code Online (Sandbox Code Playgroud)
注意:如果您没有将Permission#creator设置为与User的关联,则您需要执行此操作
Factory.create(:permission, :creator_id => @user.id)
Run Code Online (Sandbox Code Playgroud)
在类似的情况下,您可能希望更多地定义您的工厂
Factory.define :permission do |f|
f.role_id 1
f.association :group, :factory => :group
f.association :creator, :factory => :user
end
Run Code Online (Sandbox Code Playgroud)
如果您的关联设置正确,则无需担心ID,关联会为您做正确的事情.