【问题标题】:Rspec - expected ActiveRecord::RecordInvalid but nothing was raised?Rspec - 预期 ActiveRecord::RecordInvalid 但没有提出任何问题?
【发布时间】:2019-06-04 21:58:31
【问题描述】:

我正在使用 rspec 创建测试并尝试引发错误“ActiveRecord::RecordInvalid”,但我不断收到“预期的 ActiveRecord::RecordInvalid 但未引发任何错误”

我对 rspec 测试还很陌生,这实际上是我第一次直接询问有关堆栈溢出的问题。因此我的问题可能是幼稚的,所以我提前道歉。

class InsiderMailAddress < ActiveRecord::Base

   def self.get_list_by_role(role)
   address = InsiderMailAddress.find_by_role(role)
   end
end


 describe "get list by role" do    
   it "raises error when invalid role is given" do
     expect {
     InsiderMailAddress.get_list_by_role(:role)
   }.to raise_error(ActiveRecord::RecordInvalid)
   end
 end

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 rspec


    【解决方案1】:

    这是错误的例外。

    ActiveRecord::RecordInvalid 在记录无效时引发。非常不言自明。

    class Country < ApplicationRecord
      validates_presence_of :name
    end
    

    irb(main):001:0> Country.create
       (0.7ms)  BEGIN
       (0.2ms)  ROLLBACK
    => #<Country id: nil, name: nil, created_at: nil, updated_at: nil>
    irb(main):002:0> Country.create!
       (0.3ms)  BEGIN
       (0.4ms)  ROLLBACK
    ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
        from (irb):2
    

    如您所见,当您调用 .create 时它不会引发 - 但是当您调用“bang”方法 .save!.create! 时会引发。

    您可能正在寻找ActiveRecord::RecordNotFound

    irb(main):001:0> Country.find(1)
      Country Load (0.5ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
    ActiveRecord::RecordNotFound: Couldn't find Country with 'id'=1
        from (irb):1
    irb(main):002:0> Country.find_by(id: 1)
      Country Load (0.9ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
    => nil
    irb(main):003:0> Country.find_by!(id: 1)
      Country Load (0.7ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
    ActiveRecord::RecordNotFound: Couldn't find Country
        from (irb):3
    

    正如你从这个例子中看到的那样,.find_by 并没有引发它——而是它只是返回 nil。如果要引发异常,则需要改用.find_by!。这同样适用于dynamic finders

    【讨论】:

    • 我没有很好的答案来解释为什么 .find 方法不是 .find! 以保持一致性。
    • 谢谢。我很感激。
    【解决方案2】:

    您应该使用find_by! 来引发ActiveRecord::RecordNotFound 异常。

    只有验证会引发ActiveRecord::InvalidRecord,而不是ActiveRecord::RecordNotFound

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-13
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多