YoniGeek
YoniGeek

Reputation: 4093

expected Exception but nothing was raised using Rspec

I am trying to pass this last test: trying raise an exception I can't make it work My error-log:

1) VideoSearch find then whole collection of samplers failing complains if there is not any RIGHT match Failure/Error: expect(vs.find_all_by_title(2343)).to raise_error expected Exception but nothing was raised

My code:

class VideoSearch

  attr_accessor :title, :samplers

  def initialize(params)
    @title = params
    @samplers = []    
  end

  def find_all_by_title(title)
    return [] if title.blank?
    Video.where(title: title).first
  end

  def find_the_whole_collection(title)  
    if find_all_by_title(title)
      sampler = find_all_by_title(title)
      @samplers = [sampler] #add the video as the first sample
    else
      raise Exception
      return false # it's false if there 's not any match!
    end
  end
end

My spec:

describe 'find then whole collection of samplers ' do
  let(:v1) { v1 = Video.create( title: 2345 ) }
  let(:vs) { VideoSearch.new v1.title }
  let(:sample) { vs.find_all_by_title(v1.title) }

  context 'failing' do
    before :each do
      vs.stub(:find_all_by_title).and_return(nil)
    end

    it ' complains if there is not any RIGHT match ' do
      expect(vs.find_all_by_title(2343)).to raise_error
    end
  end     
end

Upvotes: 0

Views: 5100

Answers (1)

Mike Manfrin
Mike Manfrin

Reputation: 2762

Your before block is stubbing out :find_all_by_title and returning nil, so it will not raise an error. A stub basically means 'if this method is called, instead do this', so all your code will not be run when stubbed. To get your code to work, remove the before_block. Also, when testing for unfound items, convention is to pass an id of -1, so your tests could look like:

context 'failing' do
  it 'complains if there is not any RIGHT match' do
    expect( vs.find_all_by_title(-1) ).to raise_error
  end
end

Additionally, you shouldn't raise Exception, you should at the very least by raising StandardError (or, really, a subclass of StandardError that is more descriptive of what you are doing. Perhaps, make a subclass of StandardError called TitleNotFoundError?).

Also, you have redundant code in your find_whole_collection method:

if find_all_by_title(title)
  sampler = find_all_by_title(title)

can be shortened to:

if sampler = find_all_by_title(title)

If you assign a variable a nil value in an if statement, it will return false, so you only have to call find_all_by_title once.

Lastly, your find_all_by_title method returns an empty array [] if blank, but nil if not found -- this could create problems (for instance, your @samples instance variable will contain [[]] if no title is passed).

Upvotes: 2

Related Questions