16

我是 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

这解决了我的问题,这个测试通过了。

4

3 回答 3

19

你很亲密。你需要any_instance在那里添加。

Movie.any_instance.stub(:find_movies_director).and_raise(Movie::NoDirectorError)

编辑:我误读了帖子。给定电影的实例,上述内容将起作用,但不适用于 OP 的问题。

于 2013-02-18T18:35:28.010 回答
12

该错误表明它不知道该Movie::NoDirectorError异常类的定义位置。您可能需要明确require定义该类的文件,否则测试可能无法找到它。

Rails 将自动尝试constant missing使用传统的文件目录格式定位任何常量。它将根据常量的名称在load_pathatmovie/no_director_error中查找文件。movie如果找不到该文件或该文件未定义预期的常量,则您需要自己专门要求该文件。

于 2013-02-18T18:37:37.267 回答
0

在 Rails 4.1 中:

verse_selector = double("VerseSelector", select_verses: ActiveRecord::RecordNotFound.new("Verses not found"))

verse_selector.select_verses现在将返回一个ActiveRecord::RecordNotFound

于 2014-07-10T12:33:53.210 回答