How to stub error raising using Rspec in Rails?

23,889

Solution 1

The error indicates it doesn't know where that Movie::NoDirectorError exception class is defined. You might need to specifically require the file where that class is defined or the test may not be able to find it.

Rails will automatically attempt to locate any constant missing constants using a conventional file directory format. It will look for a file in the load_path at movie/no_director_error and movie based on the name of the constant. If the file is not found or the file doesn't define the expected constant than you'll need to specifically require the file yourself.

Solution 2

You're very close. You need to add any_instance in there.

Movie.any_instance.stub(:find_movies_director).and_raise(Movie::NoDirectorError)

edit: I misread the post. The above would work given an instance of Movie, but not for OP's question.

Share:
23,889
Marina K
Author by

Marina K

Updated on July 09, 2022

Comments

  • Marina K
    Marina K almost 2 years

    I'm new to Rails and Rspec and I'm using Rspec to test this controller method which includes exception handling:

    def search_movies_director
      @current_movie = Movie.find(params[:id])
      begin
        @movies = Movie.find_movies_director(params[:id])
      rescue Movie::NoDirectorError
        flash[:warning] = "#{@current_movie} has no director info"
        redirect_to movies_path
      end
    end
    

    I can't figure out how to correctly test the said path: after invalid search (when error is received) it should redirect to the homepage. I tried something like this:

    describe MoviesController do
      describe 'Finding Movies With Same Director' do
        #some other code
    
        context 'after invalid search' do
          it 'should redirect to the homepage' do
            Movie.stub(:find)
            Movie.stub(:find_movies_director).and_raise(Movie::NoDirectorError)
            get :search_movies_director, {:id => '1'}
            response.should redirect_to movies_path
          end
        end
    
      end
    end
    

    After running the test fails with an error: NameError: uninitialized constant Movie::NoDirectorError

    How to fake raising an error in this test so it actually checks whether redirect happens?

    Thanks!

    UPDATE:

    As nzifnab explained, it couldn't locate Movie::NoDirectorError. I forgot to define this exception class. So I added it to app/models/movie.rb :

    class Movie < ActiveRecord::Base
      class Movie::NoDirectorError < StandardError ; end
      #some model methods
    end
    

    This solved my problem and this test passes.

  • nzifnab
    nzifnab about 11 years
    It's not an instance method he's using, it's a class method. He has it correct.
  • Marina K
    Marina K about 11 years
    Just adding any_instance didn't work for me, still getting the same error.
  • Marina K
    Marina K about 11 years
    You are right, Movie::NoDirectorError wasn't defined anywhere. I defined this exception class in app/models/movie.rb and my test passes now. Thanks!
  • Jay Godse
    Jay Godse about 9 years
    Thank you Philip. any_instance is what finally got my test working.