Rspec тест для уникальности атрибута объекта с неопределенным методом 'valid?' для ноля:NilClass
У меня есть объект с именем "Благотворительность", и я хочу убедиться, что у каждой благотворительной организации есть уникальное имя, к сожалению, я получаю следующий неудачный тест, подозреваю, что это проблема с моими фабриками:
Failures
1) Charity name is already taken
Failure/Error: it { @charity_with_same_name.should_not be_valid }
NoMethodError:
undefined method 'valid?' for nil:NilClass
...
Благотворительный объект принадлежит_объекту пользователя. Вот благотворительность.rb:
class Charity < ActiveRecord::Base
attr_accessible :name, :description, :summary
belongs_to :user
validates :name, presence: true, uniqueness: { case_sensitive: false }, length: { maximum: 40 }
validates :summary, presence: true, length: { maximum: 140 }
validates :description, presence: true
validates :user_id, presence: true
default_scope order: 'charities.created_at DESC'
end
Вот соответствующие части charity_spec.rb:
require 'spec_helper'
describe Charity do
let(:user) { FactoryGirl.create(:user) }
#before { @charity = user.charities.build(summary: "Lorem ipsum") }
before { @charity = user.charities.build(FactoryGirl.attributes_for(:charity)) }
# this makes sure that all the attributes for charity are set, whereas
#the previous code only sets the "summary" attribute
subject { @charity }
...
describe "name is already taken" do
before do
charity_with_same_name = @charity.dup
charity_with_same_name.name = @charity.name.upcase
charity_with_same_name.save
end
it { @charity_with_same_name.should_not be_valid }
end
...
Вот этот файл factory.rb:
FactoryGirl.define do
factory :user do
sequence(:name) { |n| "Person #{n}" }
sequence(:email) { |n| "person_#{n}@example.com" }
password "foobar"
password_confirmation "foobar"
...
factory :charity do
sequence(:name) { |n| "charity #{n}" }
sequence(:summary) { |n| "summary #{n}" }
sequence(:description) { |n| "description #{n}" }
end
end
Что я сделал не так?
1 ответ
Ты можешь сделать charity_with_same_name
переменная экземпляра в вашем блоке before (изменить charity_with_same_name
в @charity_with_same_name
) и изменить it { @charity_with_same_name.should_not be_valid }
в specify { @charity_with_same_name.should_not be_valid }
чтобы это прошло.
Проблема в том, что @charity_with_same_name
не существует, потому что вы не инициализировали его. Вы только настроили charity_with_same_name
, Кроме того, из-за subject { @charity }
, it
относится к @charity
, так it { @charity_with_same_name.should_not be_valid }
здесь не имеет смысла.
РЕДАКТИРОВАТЬ: В дополнение к вышеупомянутому, вам нужно будет добавить строку @charity.save
в before
блок (прямо перед линией charity_with_same_name = @charity.dup
). Это необходимо, потому что ваша дублированная запись пройдет проверку (когда она не должна), несмотря на то, что она имеет то же имя, что и @charity
так как @charity
еще не был сохранен в базе данных. Как только благотворительность будет сохранена, проверочный тест проверит базу данных и увидит, что имя уже занято.