Я новичок в RSpec и пытаюсь разобраться, используя Factory Girl с ассоциациями в спецификациях контроллера. Сложность:
- в функциональных тестах необходимо использовать "attributes_for"
- атрибуты_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,: availability => true", он пройдет)
Предлагается ряд решений, и я думаю, что делал простые ошибки, из-за которых я не мог заставить работать ни одно из них.
1) Изменение фабрики на org_id в соответствии с предложением на этой странице не удалось выполнить ряд тестов. с сообщением «Ошибка проверки: нельзя указать организацию»
FactoryGirl.define do
factory :brand do
org_id 1002
end
end
2) Использование "symbolize_keys" выглядит многообещающим. Здесь и здесь рекомендуется использовать такой код:
(FactoryGirl.build :position).attributes.symbolize_keys
Я не знаю, как применить это в моем случае. Ниже приведено предположение, которое не сработало (выдается ошибка Нет совпадений маршрута {: controller => "бренды",: 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
Обновить
Я почти получил это, работая с ответом Шиоямы ниже, но получил сообщение об ошибке:
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) }
Что сработало!