如何在 rails/rspec 中捕获 ActiveRecord::RecordInvalid 错误

los*_*193 1 ruby rspec ruby-on-rails

我想在 Rspec 上捕获 ActiveRecord 错误:(我也在使用工厂)

规格

it "should throw an error" do
    animal = create(:animal)
    food_store = -1;
    expect(animal.update!(food_store: food_store)).to raise_error(ActiveRecord::RecordInvalid)
Run Code Online (Sandbox Code Playgroud)

验证器:

class AnimalValidator < ActiveModel::Validator
  def validate(record)
    if record.food_store < 1
      record.errors[:food_store] << "store can't be negative"
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

我不断收到此错误消息:

 Failure/Error: expect(animal.update!(food_store: new_share)).raise_error(ActiveRecord::RecordInvalid)

 ActiveRecord::RecordInvalid:
   Validation failed: store can't be negative
Run Code Online (Sandbox Code Playgroud)

我该如何捕捉这个 activeRecord 错误?

Sim*_*ime 5

使用raise_error,您需要expect一个块。如果没有块,它将执行animal.update!代码并尝试将该方法调用的返回值expect作为参数传递给该方法,但它不能,因为它已经出错了。对于块,它推迟块的执行,直到它expect告诉它运行(即,使用yield或类似)并且它给 RSpec 一个拦截异常的机会。

所以,使用:

expect { animal.update!(food_store: food_store) }.to raise_error(ActiveRecord::RecordInvalid)
Run Code Online (Sandbox Code Playgroud)

反而

  • 这是故意忽略问题的给定用例可能会使用[谓词匹配器](https://relishapp.com/rspec/rspec-expectations/v/3-9/docs/built-in-matchers/predicate -matchers), (`expect(animal).not_to be_valid` 并且目前读起来更像是您正在测试内置的 Rails 代码(如果无效,`update!` 会引发异常),而不是测试您的代码(该动物是如果有负数则无效) (2认同)