如何使用RSpec测试Rails JSON API的Jbuilder响应 - hexdevs

作者:API传播员 · 2025-12-24 · 阅读时间:3分钟

想要编写一个 Rails API 控制器测试,并确保它包含 Jbuilder 序列化程序返回的内容?你需要启用 render_views。本文将详细解释原因及其使用方法。

尽管自 rspec_rails 3.5 以来,控制器测试已不再推荐,但在许多代码库中仍然存在这些测试场景。当测试使用 Jbuilder 作为序列化器的控制器操作时,如果你想验证响应是否完全符合 Jbuilder 序列化器的预期,就需要在测试中启用 render_views


render_templaterender_views 的区别

在 RSpec 中,render_templaterender_views 是两个常见的配置选项,但它们的作用有所不同。

渲染模板

默认情况下,RSpec 允许渲染模板,但不会渲染模板的具体内容。此时,响应体是一个空字符串。这种配置适用于以下断言:

expect(response).to render_template("index")

渲染视图

启用 render_views 后,RSpec 会渲染模板的实际内容。这使得我们可以检查 JSON 响应的具体内容,例如:

expect(response.body).to eq("{email: 'email@example.com'}")

测试 Jbuilder 在 Rails 中序列化的 JSON API 响应

以下是一个简单的示例,展示如何测试 Jbuilder 序列化的 JSON API 响应。

在控制器中,我们定义了一个返回活跃用户的接口:

# app/api/v1/users/active_users_controller.rb
def index
  @users = User.active
end

在对应的 Jbuilder 视图中,我们只提取用户的部分属性:

# app/views/api/v1/users/active_users/index.json.jbuilder

json.array! @users do |user|  json.extract! user, :email, :full_name, :last_sign_in_at
end

如何使用 RSpec 测试 Rails 控制器的 JSON 响应

以下是测试上述 API 的 RSpec 示例代码:

RSpec.describe Api::V1::ActiveUsersController, type: :controller do
  render_views

# <- 你需要添加这一行!  describe "GET /index.json" do
    it "返回一个 JSON 响应,其中包含 Jbuilder 序列化程序中指定的属性" do
      get :index, format: :json
      parsed_body = JSON.parse(response.body)
      expect(parsed_body.first.keys).to contain_exactly("email", "full_name", "last_sign_in_at")
    end
  end
end

在这里,render_views 的作用是确保视图被渲染,从而使我们能够验证响应的具体内容。


render_views 添加为全局 RSpec 配置

如果你希望在所有测试中默认启用 render_views,可以在 rails_helper.rb 文件中添加以下配置:


RSpec.configure do |config|  config.render_views
end

这样,你就不需要在每个测试文件中手动添加 render_views 配置了。


通过以上方法,你可以确保 Jbuilder 序列化程序正确地渲染了你期望的内容。设置完成后,你可以安心地进行测试,确保 API 的稳定性和可靠性。

原文链接: https://www.hexdevs.com/posts/rails-jbuilder-json-api/