Rails:Rspec 和 FactoryGirl 协会
Rails: Rspec and FactoryGirl Associations
我正在尝试为我的控制器编写测试,一切都很顺利,直到我尝试为关联模型(has_many、belongs_to 等...)编写测试,我已经尝试阅读FactoryGirl 关于关联的入门指南,我已尽力遵循,但我收到如下错误:
1) GuestsController POST #create with valid attributes saves the guest to the database
Failure/Error: post :create, guest: FactoryGirl.attributes_for(@guest)
ArgumentError:
Factory not registered: #<Guest:0x007fb7b1171298>
我非常 rails 和测试新手。到目前为止,这是我得到的:
invites_controller:
...
has_many :guests
...
guests_controller:
....
belongs_to :invite
...
邀请工厂:
FactoryGirl.define do
factory :invite do |f|
f.name { Faker::Name.name }
f.invite_code { Faker::Number.number(4) }
factory :invite_with_guests do
transient do
guests_count 5
end
after(:create) do |invite, evaluator|
create_list(:guest, evaluator.guests_count, invite: invite)
end
end
end
end
客人工厂:
FactoryGirl.define do
factory :guest do |f|
f.name { Faker::Name.name }
f.attendance_status "yes"
f.starter "Mushroom"
f.main "Beef"
f.dessert "Chicken"
f.dietary_requirements { Faker::Lorem.words(4) }
f.association :invite
end
end
来宾控制器:
...
def create
@invite = Invite.find(params[:invite_id])
@guest = @invite.guests.create(guest_params)
redirect_to edit_invite_path(@invite)
end
...
来宾控制器规格:
...
describe "POST #create" do
before :each do
@invite = FactoryGirl.create(:invite_with_guests)
@guest = @invite.guests.first
end
context 'with valid attributes' do
it 'saves the guest to the database' do
expect {
post :create, guest: FactoryGirl.attributes_for(@guest)
}.to change(Guest,:count).by(1)
end
end
...
end
...
感谢所有帮助。
编辑:
路线:
Prefix Verb URI Pattern Controller#Action
invite_guests GET /invites/:invite_id/guests(.:format) guests#index
POST /invites/:invite_id/guests(.:format) guests#create
new_invite_guest GET /invites/:invite_id/guests/new(.:format) guests#new
edit_invite_guest GET /invites/:invite_id/guests/:id/edit(.:format) guests#edit
invite_guest GET /invites/:invite_id/guests/:id(.:format) guests#show
PATCH /invites/:invite_id/guests/:id(.:format) guests#update
PUT /invites/:invite_id/guests/:id(.:format) guests#update
DELETE /invites/:invite_id/guests/:id(.:format) guests#destroy
lookup_invites GET /invites/lookup(.:format) invites#lookup
invites GET /invites(.:format) invites#index
POST /invites(.:format) invites#create
new_invite GET /invites/new(.:format) invites#new
edit_invite GET /invites/:id/edit(.:format) invites#edit
invite GET /invites/:id(.:format) invites#show
PATCH /invites/:id(.:format) invites#update
PUT /invites/:id(.:format) invites#update
DELETE /invites/:id(.:format) invites#destroy
dashboard GET /dashboard(.:format) invites#index
root GET / info#index
编辑 2:
我已经根据以下可能的答案更新了访客控制器规范,它仍然失败
...
describe "POST #create" do
before :each do
@invite = FactoryGirl.create(:invite_with_guests)
@guest = @invite.guests.first
end
context 'with valid attributes' do
it 'saves the guest to the database' do
expect {
post :create, guest: @guest.attributes
}.to change(Guest,:count).by(1)
end
it 'redirects the edit invite path'
end
...
end
...
我收到以下错误:
attributes_for
接受一个符号,即 returns 您可以用来构建对象的属性。
在你的情况下,你需要
expect {
post :create, guest: @guest.attributes
}.to change(Guest,:count).by(1)
或定义guest_attributes
let(:guest_attributes){ attributes_for(:guest) }
let(:guest) { create(:guest, guest_attributes) )
...
# create an invite where the first guest is your defined guest
expect {
post :create, guest: guest_attributes
}.to change(Guest,:count).by(1)
您已经定义了您的路线,以便客人嵌套在邀请下 - 因此当您 post 客人详细信息来创建客人时,您还需要提供它嵌套在其下的邀请,并将关联和。参见:
POST /invites/:invite_id/guests(.:format) guests#create
您的 create
操作也需要 invite_id
。您也在控制器中使用 invite_id
,因此必须提供它。
尝试:
post :create, invite_id: @invite.id, guest: @guest.attributes
我正在尝试为我的控制器编写测试,一切都很顺利,直到我尝试为关联模型(has_many、belongs_to 等...)编写测试,我已经尝试阅读FactoryGirl 关于关联的入门指南,我已尽力遵循,但我收到如下错误:
1) GuestsController POST #create with valid attributes saves the guest to the database
Failure/Error: post :create, guest: FactoryGirl.attributes_for(@guest)
ArgumentError:
Factory not registered: #<Guest:0x007fb7b1171298>
我非常 rails 和测试新手。到目前为止,这是我得到的:
invites_controller:
...
has_many :guests
...
guests_controller:
....
belongs_to :invite
...
邀请工厂:
FactoryGirl.define do
factory :invite do |f|
f.name { Faker::Name.name }
f.invite_code { Faker::Number.number(4) }
factory :invite_with_guests do
transient do
guests_count 5
end
after(:create) do |invite, evaluator|
create_list(:guest, evaluator.guests_count, invite: invite)
end
end
end
end
客人工厂:
FactoryGirl.define do
factory :guest do |f|
f.name { Faker::Name.name }
f.attendance_status "yes"
f.starter "Mushroom"
f.main "Beef"
f.dessert "Chicken"
f.dietary_requirements { Faker::Lorem.words(4) }
f.association :invite
end
end
来宾控制器:
...
def create
@invite = Invite.find(params[:invite_id])
@guest = @invite.guests.create(guest_params)
redirect_to edit_invite_path(@invite)
end
...
来宾控制器规格:
...
describe "POST #create" do
before :each do
@invite = FactoryGirl.create(:invite_with_guests)
@guest = @invite.guests.first
end
context 'with valid attributes' do
it 'saves the guest to the database' do
expect {
post :create, guest: FactoryGirl.attributes_for(@guest)
}.to change(Guest,:count).by(1)
end
end
...
end
...
感谢所有帮助。
编辑:
路线:
Prefix Verb URI Pattern Controller#Action
invite_guests GET /invites/:invite_id/guests(.:format) guests#index
POST /invites/:invite_id/guests(.:format) guests#create
new_invite_guest GET /invites/:invite_id/guests/new(.:format) guests#new
edit_invite_guest GET /invites/:invite_id/guests/:id/edit(.:format) guests#edit
invite_guest GET /invites/:invite_id/guests/:id(.:format) guests#show
PATCH /invites/:invite_id/guests/:id(.:format) guests#update
PUT /invites/:invite_id/guests/:id(.:format) guests#update
DELETE /invites/:invite_id/guests/:id(.:format) guests#destroy
lookup_invites GET /invites/lookup(.:format) invites#lookup
invites GET /invites(.:format) invites#index
POST /invites(.:format) invites#create
new_invite GET /invites/new(.:format) invites#new
edit_invite GET /invites/:id/edit(.:format) invites#edit
invite GET /invites/:id(.:format) invites#show
PATCH /invites/:id(.:format) invites#update
PUT /invites/:id(.:format) invites#update
DELETE /invites/:id(.:format) invites#destroy
dashboard GET /dashboard(.:format) invites#index
root GET / info#index
编辑 2:
我已经根据以下可能的答案更新了访客控制器规范,它仍然失败
...
describe "POST #create" do
before :each do
@invite = FactoryGirl.create(:invite_with_guests)
@guest = @invite.guests.first
end
context 'with valid attributes' do
it 'saves the guest to the database' do
expect {
post :create, guest: @guest.attributes
}.to change(Guest,:count).by(1)
end
it 'redirects the edit invite path'
end
...
end
...
我收到以下错误:
attributes_for
接受一个符号,即 returns 您可以用来构建对象的属性。
在你的情况下,你需要
expect {
post :create, guest: @guest.attributes
}.to change(Guest,:count).by(1)
或定义guest_attributes
let(:guest_attributes){ attributes_for(:guest) }
let(:guest) { create(:guest, guest_attributes) )
...
# create an invite where the first guest is your defined guest
expect {
post :create, guest: guest_attributes
}.to change(Guest,:count).by(1)
您已经定义了您的路线,以便客人嵌套在邀请下 - 因此当您 post 客人详细信息来创建客人时,您还需要提供它嵌套在其下的邀请,并将关联和。参见:
POST /invites/:invite_id/guests(.:format) guests#create
您的 create
操作也需要 invite_id
。您也在控制器中使用 invite_id
,因此必须提供它。
尝试:
post :create, invite_id: @invite.id, guest: @guest.attributes