2012-03-26 31 views
2

我正在爲我的控制器來使用這些RSpec的測試:回報率 - RSpec的測試失敗,不應該

require 'spec_helper' 

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_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_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_by_director).with(@fake_movie.director).and_return(@fake_movies) 
     get :similar, {:id => "1"} 
     assigns(:movies).should == @fake_results 
    end 
    end 
end 

購買它們與該輸出失敗:

Failures: 

    1) MoviesController searching for similar movies should find the similar movies by director 
    Failure/Error: get :similar, {:id => "1"} 
     <Movie(id: integer, title: string, rating: string, description: text, release_date: datetime, created_at: datetime, updated_at: datetime, director: string) (class)> received :find_by_director with unexpected arguments 
     expected: ("George Lucas") 
       got:() 
    # ./app/controllers/movies_controller.rb:62:in `similar' 
    # ./spec/controllers/movies_controller_spec.rb:17: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"} 
     <Movie(id: integer, title: string, rating: string, description: text, release_date: datetime, created_at: datetime, updated_at: datetime, director: string) (class)> received :find_by_director with unexpected arguments 
     expected: ("George Lucas") 
       got:() 
    # ./app/controllers/movies_controller.rb:62:in `similar' 
    # ./spec/controllers/movies_controller_spec.rb:23: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"} 
     <Movie(id: integer, title: string, rating: string, description: text, release_date: datetime, created_at: datetime, updated_at: datetime, director: string) (class)> received :find_by_director with unexpected arguments 
     expected: ("George Lucas") 
       got:() 
    # ./app/controllers/movies_controller.rb:62:in `similar' 
    # ./spec/controllers/movies_controller_spec.rb:30:in `block (3 levels) in <top (required)>' 

Finished in 0.15517 seconds 
4 examples, 3 failures 

Failed examples: 

rspec ./spec/controllers/movies_controller_spec.rb:14 # MoviesController searching for similar movies should find the similar movies by director 
rspec ./spec/controllers/movies_controller_spec.rb:20 # MoviesController searching for similar movies should select the Similiar Movies template for rendering 
rspec ./spec/controllers/movies_controller_spec.rb:27 # MoviesController searching for similar movies it should make the results available to the template 

當這是我的控制器方法:

def similar 
    @movies = Movie.find_by_director(Movie.find_by_id(params[:id])) 
    end 

我不明白爲什麼這些測試失敗。

回答

1

問題是我打電話錯誤的方法。 find_by_director不是應該使用的方法,而是find_all_by_director,因此該方法發生了什麼錯誤。

+0

您是否在測試和控制器中將'find_by_director'更改爲'find_all_by_director'?或者只是一個或另一個?好奇,因爲我目前正在參加課程 – Anconia 2012-06-22 19:35:42

+1

是的,在兩者中,find_by_director似乎都不存在。 – 8vius 2012-06-22 19:42:29

+0

在控制器和測試中,我都將find_by改爲find_all,但仍然沒有運氣。有沒有你也實現的模型方法? – Anconia 2012-06-22 20:00:10

0

您需要先用正確的方法給出請求,然後測試預期的結果。

將下面的行放在失敗示例的開頭。

get :similar, {:id => "1"} 

像下面一樣。

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

這不是rspec的工作方式,首先你設置你期望的通話,然後你執行所說的呼叫 – 8vius 2012-03-26 06:57:45

+0

朋友我認爲你有點困惑與Mock.Movie.should_receive(:find_by_id).with(「1 「).and_return(@fake_movie)!=模擬(電影,:find_by_id => @fake_movie) – 2012-03-26 07:22:46

+0

我從來沒有想過它們是一樣的 – 8vius 2012-03-26 07:30:36

0

我建議你擺脫嘲諷,並在DB堅持「真實的」對象的工作:

describe MoviesController do 
    describe 'searching for similar movies' do 
    before do 
     @movie = FactoryGirl.create(:movie, 
     :title => "Star Wars", 
     :director => "George Lucas") 

     @another_lucas_movie = FactoryGirl.create(:movie, 
     :title => "Indiana Jones and the Last Crusade", 
     :director => "George Lucas") 
    end 

    it 'should find the similar movies by director' do 
     get :similar, {:id => @movie.id} 
     assigns(:movies).should include @another_lucas_movie 
    end 
    end 
end 

詳情請參閱RSpec docs

+1

這種違背單元測試的哲學 – 8vius 2012-03-26 06:57:02

+0

@ 8vius這在理論上是這樣,但實際上,即使代碼在做出一些更改後實際上失敗,模擬測試也會繼續傳遞。你應該記住它。 – 2012-03-26 08:14:58

+0

好的,我會的,這也是斯坦福大學SaaS課程的一項家庭作業,所以我正在嘗試使用他們教的一切,這就是他們這樣做的方式。任何想法爲什麼我的測試失敗? – 8vius 2012-03-26 12:41:07

0

使用FactoryGirl.create,而不是FactoryGirl.build

.build充當Model.new你有你的測試記錄保存到數據庫中。