用于ActiveRecord :: RecordNotDestroyed的RSpec匹配器

时间:2014-10-16 14:37:00

标签: ruby-on-rails rspec

我有使用TravelNotes的Rails 4应用程序。旅行笔记有3种状态:草稿,出版,存档。 如果状态是草稿,则可以将其删除,否则不会删除。

在TravelNote-Model中:

  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

显然代码正常运行,只能删除除草稿之外的其他状态的旅行记事。

如何将Failure-Message ActiveRecord :: RecordNotDestroyed变为绿色?

3 个答案:

答案 0 :(得分:1)

这里有几个问题:

  1. 您正在使用bang!destroy!版强制before_destroy回调false回复raise ActiveRecord::RecordNotDestroyed
  2. 您在方法中使用delete,在测试中使用destroy!delete没有调用回调 - 请参阅Difference between Destroy and Delete
  3. 您不应该在delete回调中拨打destroyself before_destroy。不返回false将导致原始destroy操作生效。
  4. @Felipe发布了destroy的链接,您还应该看到destroy!的链接:

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

    陈述

      

    有一系列与destroy相关的回调!如果before_destroy回调返回false,则取消操作并销毁!引发ActiveRecord :: RecordNotDestroyed。有关详细信息,请参阅ActiveRecord :: Callbacks。

答案 1 :(得分:0)

试试这个

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

了解更多信息

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

答案 2 :(得分: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