2014-10-16 3 views
1

У меня есть Rails 4 приложение с TravelNotes. Путевые заметки имеют 3 вида статусов: черновик, опубликованный, заархивированный. Если статус черновик, его можно удалить иначе.RSpec для ActiveRecord :: RecordNotDestroyed

В TravelNote-модели:

before_destroy :check_for_draft 

    def check_for_draft 
    if status == 'draft' 
     delete 
    else 
     errors.add(:scope, 'Only drafts can be deleted') 
     return false 
    end 
    end 

И я использую RSpec для тестирования:

it "should delete a travel note if its status is draft" do 
    expect{ draft.destroy! }.to change{ TravelNote.count }.by(-1) 
end 


it "should not delete a travel note if its status is published or archived" do 
    expect{ published.destroy! }.to_not change{ TravelNote.count } 

Когда я запустить тест на черновом удаление испытательных проходов, но для опубликованного-удаляемого-теста я получаю:

Failures: 
    1) TravelNote delete should not delete a travel note if its status is published or archived 
Failure/Error: expect{ published.destroy! }.to_not change{ TravelNote.count } 
ActiveRecord::RecordNotDestroyed: 
    ActiveRecord::RecordNotDestroyed 

Очевидно, что код работает и только примечания к путешествиям с другими статусами, быть удалена.

Как я могу отключить ActiveRecord-сообщение об ошибке: RecordNotDestroyed до зеленого?

ответ

0

я просто должен был удалить взрыв в уничтожить! чтобы получить тестовый проход:

it "should not delete a travel note if its status is published or archived" do 
    expect{ published.destroy }.to_not change{ TravelNote.count } 
    expect{ archived.destroy }.to_not change{ TravelNote.count } 
end 
0

Попробуйте:

expect{ published.destroy! }.to raise_error(ActiveRecord::RecordNotDestroyed) 

Для получения дополнительной информации:

http://apidock.com/rails/ActiveRecord/Persistence/destroy%21

+0

Спасибо, Фелипе, ваш подход работает. Но после удаления взрыва в уничтожении! тест проходит тоже. Я не уверен, что это rspec-способ проверки, но я придерживаюсь «to_not change». – StandardNerd

1

Есть несколько вопросов здесь:

  1. Вы используете версию bang! из destroy! которые принуждают любой before_destroy обратный вызов от возвращения false в raise ActiveRecord::RecordNotDestroyed.
  2. Вы используете delete в своем методе и destroy! в своих тестах. delete не вызывает обратные вызовы - см Difference between Destroy and Delete
  3. Вы не должны вызывать deletedestroy или из self внутри before_destroy обратного вызова. Не возвращается false приведет к тому, что действие destroy будет работать.

@Felipe разместил ссылку на destroy, вы также должны взглянуть на ссылку, чтобы destroy!:

http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-destroy-21

, который утверждает

Там есть ряд обратных вызовов, связанных с уничтожить! , Если обратный вызов before_destroy возвращает false, действие отменяется и уничтожается! вызывает ActiveRecord :: RecordNotDestroyed. Дополнительную информацию см. В разделе ActiveRecord :: Callbacks.

+0

Чтобы быть понятным, вы можете «удалять» или «уничтожать» другие связанные записи, но вы не должны «self.delete», так как обратный вызов делает это для вас –