如何在我的rails应用程序中测试ActiveRecord :: RecordNotFound?

时间:2010-03-22 12:51:01

标签: ruby-on-rails ruby testing activerecord

我的控制器中有这个代码,想要通过功能测试来测试这段代码。

raise ActiveRecord::RecordNotFound if @post.nil?

我应该使用哪种断言方法? 我使用内置的rails 2.3.5测试框架。

我尝试使用此代码:

  test "should return 404 if page doesn't exist." do
    get :show, :url => ["nothing", "here"]
    assert_response :missing
  end

但它对我不起作用。得到了这个测试输出:

test_should_return_404_if_page_doesn't_exist.(PageControllerTest):
ActiveRecord::RecordNotFound: ActiveRecord::RecordNotFound
app/controllers/page_controller.rb:7:in `show'
/test/functional/page_controller_test.rb:21:in `test_should_return_404_if_page_doesn't_exist.'

1 个答案:

答案 0 :(得分:54)

你可以做两件事。第一个是让ActionController在拯救ActiveRecord :: RecordNotFound时提供默认操作:

class PostsControllerTest < ActionController::TestCase
  test "raises RecordNotFound when not found" do
    assert_raises(ActiveRecord::RecordNotFound) do
      get :show, :id => 1234
    end
  end
end

使用此方法,您无法断言渲染的内容。你必须要相信Rails / ActionController不要改变行为。

我有时会使用的另一种选择是:

class PostsControllerTest < ActionController::TestCase
  test "renders post_missing page, and returns 404" do
    get :show, params: { :id => 1234 }

    assert_response :not_found
    assert_template "post_missing"
  end
end

class PostsController < ApplicationController
  def show
    @post = current_user.posts.find_by!(slug: params[:slug])
  end

  rescue_from ActiveRecord::RecordNotFound do
    render :action => "post_missing", :status => :not_found
  end
end

您应该在ActiveSupport API上阅读有关#rescue_from的更多信息。

为简单起见,我通常会使用我的第一个解决方案。