You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让测试环境返回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'

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 05:47:08