嗨,我在如何测试这种情况下遇到了麻烦
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: 错误
答案 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
取消引发是违反直觉的,因为这并不是按照惯例那样工作的。