我是 RSpec 的新手,并试图在控制器规范中使用带有关联的 Factory Girl。困难在于:
- 在功能测试中必须使用“attributes_for”
- attributes_for "省略任何关联"
所以如果我有这样的模型:
class Brand < ActiveRecord::Base
belongs_to :org
validates :org, :presence => true
end
class Org < ActiveRecord::Base
has_many :brands
end
还有这样的工厂:
FactoryGirl.define do
factory :brand do
association :org
end
end
此控制器规范失败:
describe BrandsController do
describe "POST create with valid params" do
it "creates a new brand" do
expect {
post :create, brand: attributes_for(:brand)
}.to change(Brand, :count).by(1)
end
end
end
(如果我注释掉“validates :org, :presence => true”,它就会通过)
提出了许多解决方案,我认为我一直在犯一些简单的错误,这意味着我无法让它们中的任何一个起作用。
1)根据此页面上的建议将工厂更改为 org_id失败了许多测试,并出现“验证失败:组织不能为空白”
FactoryGirl.define do
factory :brand do
org_id 1002
end
end
2)使用“symbolize_keys”看起来很有希望。 这里和这里建议使用这样的代码:
(FactoryGirl.build :position).attributes.symbolize_keys
我不确定如何在我的情况下应用它。下面是一个不起作用的猜测(给出错误 No route matches {:controller=>"brands", :action=>"{:id=>nil, :name=>\"MyString\", :org_id= >1052, :include_in_menu=>false, :created_at=>nil, :updated_at=>nil}"}):
describe BrandsController do
describe "POST create with valid params" do
it "creates a new brand" do
expect {
post build(:brand).attributes.symbolize_keys
}.to change(Brand, :count).by(1)
end
end
end
更新
我几乎用 Shioyama 的回答在下面得到了这个,但得到了错误消息:
Failure/Error: post :create, brand: build(:brand).attributes.symbolize_keys
ActiveModel::MassAssignmentSecurity::Error:
Can't mass-assign protected attributes: id, created_at, updated_at
因此,在这个问题之后,我将其更改为:
post :create, brand: build(:brand).attributes.symbolize_keys.reject { |key, value| !Brand.attr_accessible[:default].collect { |attribute| attribute.to_sym }.include?(key) }
哪个有效!