0

У меня есть объект под названием «Благотворительность», и я хочу удостовериться, что каждая благотворительность имеет уникальное имя, к сожалению, я получаю следующий неудачный тест, я подозреваю, что это проблема с моими заводами:Rspec тест для уникальности атрибута объекта недействителен с неопределенным методом 'valid?' для nil: 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 
     ... 

Объект милосердия принадлежит _объекту пользователя. Вот charity.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 

Что я сделал неправильно?

ответ

0

Вы можете сделать charity_with_same_name переменную экземпляра в вашем перед блоком (изменение 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 еще не сохранен в базе данных. После сохранения благотворительности тест проверки проверяет базу данных и показывает, что имя уже выполнено.

+0

Благодарим за помощь, но добавив @ в каждый экземпляр charity_with_same_name и заменив «it» на «указать», возвращали сбой: Укажите {«at» charity_with_same_name.should_not be_valid} ожидаемый допустимый? вернуть ложь, получилось правдой. Добавляя @ только к первому экземпляру (я не думаю, что это то, что вы имели в виду), возвращали сбой: Failure/Error: charity_with_same_name.name = "at" charity.name.upcase, NameError: неопределенная локальная переменная или метод 'charity_with_same_name'. .. Я сделал что-то не так? SO не позволит мне использовать @, поэтому я заменил его на «at» – user1424388

+0

@ user1424388 См. Мое редактирование. – cdesrosiers

+0

Вот и все! Большое спасибо. – user1424388