如何让测试环境返回404错误而非抛出ActiveRecord::RecordNotFound异常?
解决Rails测试环境中无效ID请求未捕获ActiveRecord异常的问题
我想要编写测试,验证应用在请求无效记录(例如id=0的记录)时返回
404 Not Found。我的测试代码如下:get '/pluralized_name_for_my_resource/0', as: :json assert_response :not_found, "Doesn't return 404 Not Found for invalid id"在浏览器中访问对应URL(如
http://localhost:3000/pluralized_name_for_my_resource/0.json)时,应用内部会抛出ActiveRecord异常(日志中会打印相关信息),但能正确返回404 Not Found。然而运行测试时,异常未被同样处理,测试在执行第一条get '/pluralized_...语句时就终止,并被标记为错误。请问如何让测试环境像开发环境一样处理该异常,使测试通过?
在Rails测试环境中,默认不会自动捕获ActiveRecord::RecordNotFound这类异常并转化为404响应——开发环境的异常捕获由ActionDispatch::ShowExceptions中间件处理,但测试环境默认关闭了该中间件的异常捕获逻辑,目的是让开发者能看到测试中抛出的原始异常。
以下是三种可行的解决方法:
方案1:针对单个测试类启用异常捕获中间件
如果仅需在特定控制器测试中生效,可以在测试类中配置启用ActionDispatch::ShowExceptions:
class MyResourceControllerTest < ActionDispatch::IntegrationTest setup do # 重新构建包含异常捕获中间件的应用实例 @app = Rack::Builder.new do use ActionDispatch::ShowExceptions run Rails.application end.to_app end test "returns 404 for invalid resource id" do get '/pluralized_name_for_my_resource/0', as: :json assert_response :not_found, "Doesn't return 404 Not Found for invalid id" end end
方案2:单个测试用例中手动捕获异常
如果不想修改测试类配置,可在单个测试里手动捕获异常并模拟404响应:
test "returns 404 for invalid resource id" do begin get '/pluralized_name_for_my_resource/0', as: :json rescue ActiveRecord::RecordNotFound @response.status = 404 end assert_response :not_found, "Doesn't return 404 Not Found for invalid id" end
方案3:全局开启测试环境的异常捕获
若希望所有测试都自动处理这类异常,可修改config/environments/test.rb配置:
# config/environments/test.rb Rails.application.configure do # 其他配置... config.action_dispatch.show_exceptions = true end
注意:全局开启后,所有可转化为HTTP错误的异常都会被自动处理,可能隐藏部分测试问题,建议优先使用方案1按需启用。
内容的提问来源于stack exchange,提问作者dB'
相关产品推荐
相关产品推荐

