user10893133
user10893133

Reputation:

Rspec - expected ActiveRecord::RecordInvalid but nothing was raised?

I'm creating tests using rspec and trying to raise an error "ActiveRecord::RecordInvalid", but I keep getting "expected ActiveRecord::RecordInvalid but nothing was raised"

I'm pretty new to rspec testing and this is actually my first time directly asking a question on stack overflow. Thus my question might be juvenile, so I do apologize in advance.

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

Upvotes: 1

Views: 1822

Answers (2)

max
max

Reputation: 102343

Thats the wrong exception.

ActiveRecord::RecordInvalid is raised when a record is invalid. Pretty self explanatory.

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

As you can see it is not raised when you call .create - but it is when you call the "bang" methods .save! and .create!.

What you may be looking for is 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

As you can see from this example it is not raised by .find_by - rather it just returns nil. If you want to raise an exception then you need to use .find_by! instead. The same applies to dynamic finders.

Upvotes: 2

William Tran
William Tran

Reputation: 269

you should use find_by! to raise ActiveRecord::RecordNotFound exception.

Only validations raise ActiveRecord::InvalidRecord, not ActiveRecord::RecordNotFound

Upvotes: 1

Related Questions