2012-03-26 33 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你有你的测试记录保存到数据库中。