1

rspecを使用していますが、いくつか問題があります。rspecで次のエラーが発生します

  1) MoviesController find movies with same director should call the model method that searches for movie by director
     Failure/Error: get :samedirector, {:id => 1}
     RuntimeError:
       Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
     # ./app/controllers/movies_controller.rb:63:in `samedirector'
     # ./spec/controllers/movies_controller_spec.rb:11:in `block (3 levels) in <top (required)>'

これは私のmovies_controller_spec.rbです

describe MoviesController do  
  describe 'find movies with same director' do  
    let(:movie) { Movie.create }  
    before {movie.id=1, movie.director = "Steven S", movie.title="Hello World"}  
    subject { movie }  
    it 'should call the model method that searches for movie by director' do  
      Movie.should_receive(:find).with("1")  
      #this get is passing a nil id  
      get :samedirector, {:id => movie.id}  
    end  
  end  
end  

これは私のMovieController.rbです

def samedirector  
    movie = Movie.find(params[:id])  
    @director = movie.director  
  end  

どんな助けでもいただければ幸いです。これは宿題の問題なので、ソリューションコードよりも直感的に理解して、間違っている可能性のある行を指摘していただければ、非常に役立ちます。

アップデート

私はあなたが言ったことに基づいてそれを修正し、ちょうどそれを初期化しました

before (:each) do
  @movie = Movie.create(:director => "Steven S", :title=>"Hello World")
end  

しかし、私は今、次の問題を抱えています。監督がコントローラーのスティーブンSであることを認識していないようです。理由はわかりません。

4

2 に答える 2

1

nilオブジェクトで.idメソッドを呼び出しています。

2つの場所で.idを呼び出しています。

before {movie.id=1, movie.director = "Steven S", movie.title="Hello World"} 

get :samedirector, {:id => movie.id}  

少なくとも1つの場所で、movie==nil。そのため、このエラーが発生します。事実上、あなたはnil.idを求めています

混乱を引き起こしているので、とmovieの両方で初期化しようとしないでください。また、ローカル変数はメソッドが異なるため(したがって、ローカルスコープが異なるため)、句から句に渡されません。代わりにインスタンス変数を使用してください。letbeforebeforeit

代わりに、before句のみを使用し、代わりに@movieと呼びます。

before(:each) do
  @movie = Movie.create(:id => 1, :director => "SS", :title => "hello")
end

it '...' do
  Movie.should_receive(:find).with("1") 
  get :samedirector, {:id => @movie.id}  
end

ただし、作成行には注意してください。attr_accessibleなどがある場合、実際にはすべての属性が保存されない可能性があります。その場合は、次のものが必要になる可能性があります。

before(:each) do
  @movie = Movie.create
  @movie.director = "asdf"
  @movie.title = "asdf"
  @movie.save
end
于 2012-08-19T09:47:30.453 に答える
0

あなたがするとき

Movie.should_receive(:find).with("1") 

あなたがするときに何が起こるかを変えていますMovie.find(1)。これは、元の実装に置き換わるものです(つまりshould_receive、テストスパイではありません)。特に、戻り値はnilです(デフォルト)。Movie.findこれは、 nilを返すことを期待していないため、アプリコードを壊します

and_return返す値を制御するために使用できます

Movie.should_receive(:find).with("1").and_return(movie)
于 2012-08-19T10:03:20.593 に答える