使用 RSpec 测试 Rails JSON API - Nimble

作者:API传播员 · 2025-12-23 · 阅读时间:5分钟
本文详细介绍了如何使用RSpec测试Rails JSON API,包括安装和配置必要的Gem如rspec-rails、jsonapi-serializer、fabrication和json_matchers,定义API端点如GET、POST和DELETE,并编写测试用例来验证JSON响应结构和行为,从而提高开发效率和代码质量。

设置必要的 Gem

在本文中,我们将介绍如何使用 RSpec 测试 Rails JSON API。为了提升测试的便捷性,我们需要安装并配置以下 Gem。

安装 RSpec Rails

首先,添加 rspec-rails 到 Gemfile 中,然后运行以下命令以安装它:

bundle install

安装完成后,运行以下命令在 Rails 应用程序中配置 RSpec:

rails generate rspec:install

此命令会生成一些样板文件,用于配置 Rails 应用程序的 RSpec 测试环境。

安装 JSONAPI 序列化程序、工厂工具和 JSON 匹配器

接下来,我们需要安装以下 Gem:

  • jsonapi-serializer
  • fabrication(用于生成测试数据)
  • json_matchers(用于验证 JSON 响应)

将这些 Gem 添加到 Gemfile 中,然后运行以下命令安装它们:

bundle install

安装完成后,还需要对这些 Gem 进行 RSpec 配置,以便在测试中使用。


API 终结点

在本次演示中,我们将使用以下类和 API 端点:

  • GET /api/books:获取图书列表
  • POST /api/books:创建新图书
  • DELETE /api/books/:id:删除指定图书

API 端点的示例响应

以下是各 API 端点的示例响应:

  • 获取图书列表:成功响应状态码为 200,返回一个包含图书列表的 JSON 数据。

  • 创建图书:成功响应状态码为 201,无响应主体;错误响应示例如下:

    {
    "errors": [
      {
        "status": "422",
        "title": "Invalid Attribute",
        "detail": "Title can't be blank"
      }
    ]
    }
  • 删除图书:成功响应状态码为 204,无响应主体。


使用 RSpec 测试端点

接下来,我们将为上述 API 端点编写测试。

工厂设置

首先,我们需要定义一个 Book 工厂,以便在测试中快速生成 Book 实例。以下是 Book 工厂的定义:

Fabricator(:book) do
  title { "Sample Book Title" }
  author { "Sample Author" }
end

定义完成后,我们可以在测试中通过以下方式轻松创建 Book 实例:

Fabricate(:book)

定义 JSON 模式

为了验证 API 响应的结构,我们需要定义 JSON Schema:

  • spec/support/api/schemas/books.json 中定义 Book 的 JSON Schema
  • spec/support/api/schemas/errors.json 中定义错误响应的 JSON Schema。

以下是 Book JSON Schema 的示例:

{
  "type": "object",
  "required": ["id", "title", "author"],
  "properties": {
    "id": { "type": "integer" },
    "title": { "type": "string" },
    "author": { "type": "string" }
  }
}

测试 GET /api/books 端点

我们为获取图书列表的 API 编写以下测试:

RSpec.describe "GET /api/books", type: :request do
  it "returns a 200 status code" do
    get "/api/books"
    expect(response).to have_http_status(:ok)
  end

  it "returns a list of books" do
    Fabricate.times(3, :book)
    get "/api/books"
    expect(response.body).to match_json_schema("books")
  end
end

运行测试命令:

rspec spec/requests/api/books_controller_spec.rb

测试通过后,您将看到所有测试均成功。

测试 POST /api/books 端点

以下是创建图书 API 的测试代码:

RSpec.describe "POST /api/books", type: :request do
  context "with valid parameters" do
    let(:valid_params) { { title: "New Book", author: "Author Name" } }

    it "returns a 201 status code" do
      post "/api/books", params: valid_params
      expect(response).to have_http_status(:created)
    end    it "returns an empty response body" do
      post "/api/books", params: valid_params
      expect(response.body).to be_empty
    end
  end  context "with invalid parameters" do
    let(:invalid_params) { { title: "" } }    it "returns a 422 status code" do
      post "/api/books", params: invalid_params
      expect(response).to have_http_status(:unprocessable_entity)
    end    it "returns a JSON:API compliant error response" do
      post "/api/books", params: invalid_params
      expect(response.body).to match_json_schema("errors")
    end
  end
end

运行测试命令:

rspec spec/requests/api/books_controller_spec.rb

所有测试通过后,您将看到测试结果。

测试 DELETE /api/books/:id 端点

以下是删除图书 API 的测试代码:

RSpec.describe "DELETE /api/books/:id", type: :request do
  let!(:book) { Fabricate(:book) }

  it "returns a 204 status code" do
    delete "/api/books/#{book.id}"
    expect(response).to have_http_status(:no_content)
  end  it "returns an empty response body" do
    delete "/api/books/#{book.id}"
    expect(response.body).to be_empty
  end
end

运行测试命令:

rspec spec/requests/api/books_controller_spec.rb

测试通过后,您将看到所有测试均成功。


结论

在 Rails 开发中,为代码编写测试已成为行业标准。通过为 API 端点编写测试,我们可以确保 API 响应的正确性和一致性。借助 RSpec 和相关工具(如 json_matchersfabrication),我们能够快速验证 API 的行为和响应结构,从而提高开发效率和代码质量。

原文链接: https://nimblehq.co/blog/testing-rails-json-api-with-rspec