【问题标题】:How to stub error raising using Rspec in Rails?如何在 Rails 中使用 Rspec 存根错误引发?
【发布时间】:2013-02-03 06:27:11
【问题描述】:

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

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

【问题讨论】:

    标签: ruby-on-rails ruby unit-testing rspec stubbing


    【解决方案1】:

    你很亲密。您需要在其中添加any_instance

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

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

    【讨论】:

    • 他用的不是实例方法,是类方法。他说得对。
    • 仅添加 any_instance 对我不起作用,仍然出现相同的错误。
    • 谢谢菲利普。 any_instance 是最终让我的测试工作的原因。
    【解决方案2】:

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

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

    【讨论】:

    • 你说得对,Movie::NoDirectorError 没有在任何地方定义。我在app/models/movie.rb 中定义了这个异常类,现在我的测试通过了。谢谢!
    【解决方案3】:

    在 Rails 4.1 中:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-09
      • 1970-01-01
      • 2019-11-07
      • 1970-01-01
      • 2014-04-04
      • 1970-01-01
      相关资源
      最近更新 更多