使用rspec

时间:2018-10-18 00:10:06

标签: ruby-on-rails ruby rspec

嗨,我在如何测试这种情况下遇到了麻烦

models / checklist.rb

before_destroy :destroyable?

def destroyable?
 raise "Error" if phase.companies.count > 0
end

spec / models / checklist_spec.rb

describe 'triggers' do
 describe 'destroyable?' do
  it 'should raise error if checklist phase has companies' do
    company = create(:company)
    company2 = create(:company)
    phase = create(:phase, company_ids: [company.id, company2.id])

    checklist = create(:checklist, phase: phase)

    expect(checklist.destroy).to raise_error(RuntimeError)
  end
 end
end

我收到此错误: RuntimeError:        错误

2 个答案:

答案 0 :(得分:2)

您必须将引发错误的代码包装在一个块中,

expect { checklist.destroy }.to raise_error(RuntimeError)

答案 1 :(得分:0)

例外情况应用于例外情况,您的情况并非例外。对于rails 4,您应该返回false,对于rails 5,您应该调用throw(:abort)以防止记录被破坏。

您可以添加错误(以获得一些反馈),然后在条件为真时中止:

before_destroy :destroyable?

def destroyable?
  return true if phase.companies.count == 0
  errors.add(:companies, 'is not empty')
  throw(:abort)
end

现在您可以像这样测试:

checklist.destroy
expect(checklist).not_to be_destroyed
expect(checklist.errors[:companies]).to eq 'is not empty'

检查回调DOC,“取消回调”部分https://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

编辑: 如果在记录未销毁时仍希望有一个异常,则before_destroy回调将是相同的,但是您调用destroy!(请注意“!”爆炸),这会引发ActiveRecord::RecordNotDestroyed异常。

将异常作为destroy取消引发是违反直觉的,因为这并不是按照惯例那样工作的。