我是Rails和Rspec的新手,我正在使用Rspec来测试这个包含异常处理的控制器方法:
def search_movies_director
@current_movie = Movie.find(params[:id])
begin
@movies = Movie.find_movies_director(params[:id])
rescue Movie::NoDirectorError
flash[:warning] = "#{@current_movie} has no director info"
redirect_to movies_path
end
end
我无法弄清楚如何正确测试所述路径:在无效搜索后(收到错误时),它应该重定向到主页。我试过这样的事情:
describe MoviesController do
describe 'Finding Movies With Same Director' do
#some other code
context 'after invalid search' do
it 'should redirect to the homepage' do
Movie.stub(:find)
Movie.stub(:find_movies_director).and_raise(Movie::NoDirectorError)
get :search_movies_director, {:id => '1'}
response.should redirect_to movies_path
end
end
end
end
运行测试后失败并显示错误:NameError: uninitialized constant Movie::NoDirectorError
如何伪造在此测试中引发错误,以便它实际检查重定向是否发生?
谢谢!
更新
正如nzifnab解释的那样,它找不到Movie::NoDirectorError
。我忘了定义这个异常类。所以我把它添加到app/models/movie.rb
:
class Movie < ActiveRecord::Base
class Movie::NoDirectorError < StandardError ; end
#some model methods
end
这解决了我的问题,这个测试通过了。
答案 0 :(得分:19)
你非常接近。您需要在其中添加any_instance
。
Movie.any_instance.stub(:find_movies_director).and_raise(Movie::NoDirectorError)
编辑:我误读了帖子。上面的内容适用于Movie的一个实例,但不适用于OP的问题。
答案 1 :(得分:12)
错误表明它不知道Movie::NoDirectorError
异常类的定义位置。您可能需要专门require
定义该类的文件,否则测试可能无法找到它。
Rails将使用传统的文件目录格式自动尝试查找任何constant missing
常量。它将根据常量的名称在load_path
movie/no_director_error
和movie
查找文件。如果找不到文件或文件没有定义预期的常量,那么你需要自己特别要求文件。
答案 2 :(得分:0)
在Rails 4.1中:
verse_selector = double("VerseSelector", select_verses: ActiveRecord::RecordNotFound.new("Verses not found"))
verse_selector.select_verses
现在将返回ActiveRecord::RecordNotFound