web-dev-qa-db-ja.com

RailsでRspecを使用してエラー発生をスタブする方法は?

私はRailsとRspecを初めて使用し、Rspecを使用して例外処理を含むこのコントローラーメソッドをテストしています。

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

上記のパスを正しくテストする方法がわかりません。無効な検索の後(エラーを受け取った場合)、ホームページにリダイレクトする必要があります。私はこのようなことを試みました:

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

テストの実行後、エラーで失敗します:NameError: uninitialized constant Movie::NoDirectorError

このテストでエラーを発生させて、リダイレクトが実際に発生するかどうかを実際にチェックするようにするにはどうすればよいですか?

ありがとう!

更新:

Nzifnabが説明したように、Movie::NoDirectorErrorを見つけることができませんでした。この例外クラスを定義するのを忘れました。だから私はそれをapp/models/movie.rbに追加しました:

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

これで私の問題は解決し、このテストに合格しました。

16
Marina K

このエラーは、そのMovie::NoDirectorError例外クラスがどこで定義されているかがわからないことを示しています。そのクラスが定義されているファイルを具体的にrequireする必要がある場合があります。そうしないと、テストでファイルを見つけることができない場合があります。

Railsは、従来のファイルディレクトリ形式を使用して、constant missing定数を自動的に見つけようとします。定数の名前に基づいて、load_pathおよびmoviemovie/no_director_errorでファイルを検索します。ファイルが見つからない場合、またはファイルが期待される定数を定義していない場合は、ファイルを自分で具体的に要求する必要があります。

12
nzifnab

あなたはとても近いです。そこにany_instanceを追加する必要があります。

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

編集:私は投稿を読み間違えました。上記はMovieのインスタンスがあれば機能しますが、OPの質問には機能しません。

19

In Rails 4.1:

verse_selector = double("VerseSelector", select_verses: ActiveRecord::RecordNotFound.new("Verses not found"))

verse_selector.select_versesActiveRecord::RecordNotFoundを返すようになりました

0
fkoessler