1

一時的に多かれ少なかれ私のために働いていた名前で監督を検索するための一連のテストがありました。の線に沿って:

describe MoviesController do
  before :each do
    @fake_results = [mock(Movie),mock(Movie)]
  end
  it "should call the model that looks for same director movies" do
    Movie.should_receive(:find_by_same_director).with('Woody Allen').and_return(@fake_results)
    post :find_by_same_director, {:name => 'Woody Allen'}
  end

などなど。これはそれほどひどく何も壊していませんでした。残念ながら、名前ではなくidパラメーターを使用するようにコントローラーメソッドを変更する必要があると判断しました。コードの2番目の部分は次のようになります。

it "should call the model that looks for same director movies" do
  Movie.should_receive(:find_by_same_director).with(:id => 1).and_return(@fake_results)
  post :find_by_same_director, {:id => 1}
end

現在スペックを実行すると、次のエラーが発生します。

  1) MoviesController finding movies with same director should call the model method that looks for same director movies
     Failure/Error: post :find_by_same_director, {:id => 1}
     ActiveRecord::RecordNotFound:
       Couldn't find Movie with id=1
     # ./app/controllers/movies_controller.rb:62:in `find_by_same_director'
     # ./spec/controllers/movie_controller_spec.rb:12:in `block (3 levels) in <top (required)>'

id = 1の実際の映画がないことが、深刻なエラーを引き起こしているのはなぜですか?私のスタブ/モックはもう私を覆っていませんか?以前、ウディ・アレン監督の映画はありませんでした。テストでID1の映画が存在するふりをするために何をする必要がありますか?

編集:

コントローラの動作は次のとおりです。

  def find_by_same_director
   @movie = Movie.find params[:id]
   @movies = Movie.find_same_director(@movie.id)
   if @movies.count == 1
    flash[:notice] = "'#{@movie.title}' has no director info"
    redirect_to movies_path
   end
  end

これがハッシュを期待しているかどうかわからない...?

4

1 に答える 1

1

コントローラーはハッシュまたは整数 ID を使用find_by_same_directorしてモデルのメソッドを呼び出しますか? Movie後者の場合、設定したモックは機能しません。これは、 has{:id => 1}で呼び出す必要があることを指定しているためです。したがって、次のように変更する必要があります。

Movie.should_receive(:find_by_same_director).with(1).and_return(@fake_results)

モックの期待値を a で指定する場合with、渡される引数は正確に一致する必要があります。それらが一致しない場合は、モックされていないfind_by_same_directorメソッドが呼び出されます。任意の引数のメソッドをモックしたい場合は、with完全に省略することができます:

Movie.should_receive(:find_by_same_director).and_return(@fake_results)

編集:

コントローラーのアクションを見ると、次のようにMovie.findメソッドをモックする必要がありfind_same_directorます。

Movie.should_receive(:find).with('1').and_return(mock_model(:id => 1))

または単にスタブします(メソッドが呼び出されることをアサートしたくない場合):

Movie.stub(:find).and_return(mock_model(:id => 1))

find_by_same_directorまた、コントローラーが呼び出しているのに対し、仕様がメソッドをモックしていることにも気付きましたfind_same_director。それは単なるタイプミスですか?

于 2012-08-12T20:09:01.153 に答える