How can I test ActiveRecord::RecordNotFound in my rails app?
I have this code in my controller and want to test this code line with a functional test.
raise ActiveRecord::RecordNotFound if @post.nil?
which assert method should I use? I use the built-in rails 2.3.5 test fr开发者_如何学Pythonamework.
I tried it with this code:
test "should return 404 if page doesn't exist." do
get :show, :url => ["nothing", "here"]
assert_response :missing
end
but it doesn't work for me. Got this test output:
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.'
There are two things you can do. The first is to let ActionController provide the default action when it rescues 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
Using this method, you can't assert what gets rendered. You have to trust Rails/ActionController not to change behaviour.
An alternative, which I've sometimes used, is this:
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
You should read more about #rescue_from on the ActiveSupport API.
For simplicity, I usually go with my 1st solution though.
精彩评论