【发布时间】:2015-12-02 08:55:05
【问题描述】:
我是 RSpec 的新手。我正在使用以下(正确的)规范代码来确保在测试控制器中调用方法 find 和 same_director:
require 'rails_helper'
describe MoviesController do
describe 'Searching movies for same director: ' do
before :each do
@movie1 = instance_double('Movie', id:1, title:'movie1')
@movie2 = instance_double('Movie', id:2, title:'movie2')
@any_possible_id = 1
end
it 'should call the model method that finds the movie corresponding to the passed id.' do
allow(@movie1).to receive(:same_directors).and_return [@movie1,@movie2]
expect(Movie).to receive(:find).with(@any_possible_id.to_s).and_return @movie1
get :directors, :id=>@any_possible_id
end
it 'should call the model method that finds the movies corresponding to the same director.' do
expect(@movie1).to receive(:same_directors).and_return [@movie1,@movie2]
allow(Movie).to receive(:find).with(@any_possible_id.to_s).and_return @movie1
get :directors, :id=>@any_possible_id
end
这工作正常,但如您所见,两个it-子句包含重复的get :directors, :id=>@any_possible_id 行。鉴于控制器中语句的顺序(请参阅问题末尾的控制器代码),get 必须出现在 it 子句的末尾。挑战在于通过将其移至before-clause 来将其干燥。
当然,最好的解决方案是将其移至 after-clause (我意识到,当我写这个问题时,我做到了并且它有效。)但我现在想要了解为什么我使用 Spies这里不工作。
我对间谍的(失败)尝试是:
describe MoviesController do
describe 'Searching movies for same director: ' do
before :each do
@movie1 = instance_double('Movie', id:1, title:'movie1')
@movie2 = instance_double('Movie', id:2, title:'movie2')
@any_possible_id = 1
@spyMovie = class_spy(Movie)
@spymovie1 = instance_spy(Movie)
get :directors, :id=>@any_possible_id
end
it 'should call the model method that finds the movie corresponding to the passed id.' do
allow(@spymovie1).to receive(:same_directors)#.and_return [@movie1,@movie2]
expect(@spyMovie).to have_received(:find).with(@any_possible_id.to_s)#.and_return @movie1
end
it 'should call the model method that finds the movies corresponding to the same director.' do
expect(@spymovie1).to have_received(:same_directors)#.and_return [@movie1,@movie2]
allow(@spyMovie).to receive(:find).with(@any_possible_id.to_s)#.and_return @movie1
end
现在,第二段代码可能有几个问题,但是我在运行rspec 时遇到的错误是:
1) MoviesController Searching movies for same director: should call the model method that finds the movie corresponding to the passed id.
Failure/Error: expect(@spyMovie).to have_received(:find).with(@any_possible_id.to_s)#.and_return @movie1
(ClassDouble(Movie) (anonymous)).find("1")
expected: 1 time with arguments: ("1")
received: 0 times
# ./spec/controllers/movies_controller_spec.rb:32:in `block (3 levels) in <top (required)>'
2) MoviesController Searching movies for same director: should call the model method that finds the movies corresponding to the same director.
Failure/Error: expect(@spymovie1).to have_received(:same_directors)#.and_return [@movie1,@movie2]
(InstanceDouble(Movie) (anonymous)).same_directors(*(any args))
expected: 1 time with any arguments
received: 0 times with any arguments
# ./spec/controllers/movies_controller_spec.rb:35:in `block (3 levels) in <top (required)>'
因此,您可以看到,当我使用间谍时,没有检测到对 :find 和 :same_directors 的调用。
我无法在rspec.info 和relishapp 中得到答案。如果您能提出一些建议,我将不胜感激。谢谢!
如果您需要,这就是控制器:
def directors
@movie = Movie.find(params[:id])
@movies = @movie.same_directors
if (@movies-[@movie]).empty?
flash[:notice] = "'#{@movie.title}' has no director info"
redirect_to movies_path
end
end
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-4 rspec rspec-rails