2012-06-25 35 views
1

我收到了我的Rspec的测试中轨Rspec的失败中轨

1) MoviesController searching for similar movies should find the similar movies by director 
    Failure/Error: get :similar, {:id => "1"} 
    ActiveRecord::RecordNotFound: 
     Couldn't find Movie with id=1 
    # ./app/controllers/movies_controller.rb:63:in `similar' 
    # ./spec/controllers/movies_controller_spec.rb:16:in `block (3 levels) in <top (required)>' 

    2) MoviesController searching for similar movies should select the Similiar Movies template for rendering 
    Failure/Error: get :similar, {:id => "1"} 
    ActiveRecord::RecordNotFound: 
     Couldn't find Movie with id=1 
    # ./app/controllers/movies_controller.rb:63:in `similar' 
    # ./spec/controllers/movies_controller_spec.rb:22:in `block (3 levels) in <top (required)>' 

    3) MoviesController searching for similar movies it should make the results available to the template 
    Failure/Error: get :similar, {:id => "1"} 
    ActiveRecord::RecordNotFound: 
     Couldn't find Movie with id=1 
    # ./app/controllers/movies_controller.rb:63:in `similar' 
    # ./spec/controllers/movies_controller_spec.rb:29:in `block (3 levels) in <top (required)>' 

这是我的控制器方法如下错误是导致它失败:

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

我不能理解为什么这个测试不会出现同样的错误。任何帮助,将不胜感激

下面是测试

describe MoviesController do 
    describe 'searching for similar movies' do 
    before :each do 
     @fake_movies = [mock('Movie'), mock('Movie')] 
     @fake_movie = FactoryGirl.build(:movie, :id => "1", :title => "Star Wars", :director => "George Lucas") 
end 
it 'should follow the route to the similar movies by director page' do 
    assert_routing('movies/1/similar', {:controller => 'movies', :action => 'similar', :id => '1'}) 
end 

it 'should find the similar movies by director' do 
    Movie.should_receive(:find_by_id).with("1").and_return(@fake_movie) 
    Movie.should_receive(:find_all_by_director).with(@fake_movie.director).and_return(@fake_movies) 
    get :similar, {:id => "1"} 
end 

it 'should select the Similiar Movies template for rendering' do 
    Movie.should_receive(:find_by_id).with("1").and_return(@fake_movie) 
    Movie.should_receive(:find_all_by_director).with(@fake_movie.director).and_return(@fake_movies) 
    get :similar, {:id => "1"} 
    response.should render_template('similar') 
end 

it 'it should make the results available to the template' do 
    Movie.should_receive(:find_by_id).with("1").and_return(@fake_movie) 
    Movie.should_receive(:find_all_by_director).with(@fake_movie.director).and_return(@fake_movies) 
    get :similar, {:id => "1"} 
    assigns(:movies).should == @fake_results 
end 
end 
end 

FactoryGirl的设置如下:

FactoryGirl.define do 
    factory :movie do 
    title 'Star Wars' 
    director 'George Lucas' 
    end 
end 
+1

当你执行'Movie.find(params [:id])'时,它没有找到你的电影。您是否在Rspec测试中设置了电影对象?你确定它有ID = 1吗?它很可能不会。 – MrDanA

+0

你能否展示失败的测试? –

+0

请注意使用测试数据库,而不是开发数据库。 您可能还没有设置任何测试电影,我可以建议FactoryGirl吗? –

回答

4

的规范要求Factory.build。这不会将对象持久保存到数据库中。您需要使用Factory.create以允许Movie.find工作。

+3

是的,这就是你的问题。 个人而言,如果可能的话,我会尽量避免在测试中使用ID,并且会将'get:similar,{:id =>“1”}这样的一行更改为'get:similar,{:id => @fake_movie .id}',但是使用create而不是build的方法是要走的路。 –

+0

这个伎俩!而@NilsLandt也非常感谢你的洞察力 – Anconia