Rspec を使用して TDD の旅を開始し、いくつかの問題を抱えています。if ... OR 条件で rspec が失敗する理由がわかりません。
def director
@movie = Movie.find_by_id(params[:id])
if @movie.nil? or @movie.director.empty?
flash[:notice] = "The movie has no director info"
redirect_to movies_path
else
# success
end
end
Rspec テスト:
before ... #stubs
it 'assigns movies array in director action' do
Movie.stub(:find_by_id).and_return(@movie)
get "director", :id => 1
...
end
エラー:
1) MoviesController assigns movies array in director action
Failure/Error: get "director", :id => 1
NoMethodError:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.empty?
レコードが見つからない場合、@movie.nil? 条件を満たす必要があり、@movie.director.empty? に対して評価すべきではありません。あれは正しいですか?
この場合、そのようなレコードがなくても、要求されたレコードのディレクター フィールドが空白であっても、同じように扱います。
あなたの助けに感謝。
アップデート
次のように、いくつかのコントローラーをモデルから削除しました。
コントローラ:
def director
@movies = Movie.same_director_by_id(params[:id])
if @movies.blank?
redirect_to movies_path
end
end
映画:
def self.same_director_by_id (id)
movie = self.find_by_id(id)
if movie.nil? or movie.director.blank?
return []
else
return self.where("id != ?", id).find_all_by_director(movie.director)
end
end
rspec:
it 'assigns movies array in director action' do
Movie.should_receive(:same_director_by_id).and_return([@movie])
get "director", :id => 1
assigns(:movies).should be_kind_of(Array)
end
これで、すべてのコントローラーの仕様が見事に合格しました。モデルを個別にテストします。
更新 2:
問題は、モックではなくモデルで :director をスタブしたことです! アプネダイビングは正しかった。