请求规格

请求规格为 Rails 集成测试提供了薄包装器,旨在通过完整的堆栈驱动行为,包括路由(由 Rails 提供)并且不进行存根(这取决于你)。

请求规格通过 `type: :request` 标记,或者如果你设置了 `config.infer_spec_type_from_file_location!`,则通过将其放在 `spec/requests` 中来标记。

使用请求规格,你可以

查看 Rails 文档了解有关集成测试的更多信息。

RSpec 提供了两个匹配器,它们委托给 Rails 断言

  render_template # delegates to assert_template
  redirect_to     # delegates to assert_redirected_to

查看 Rails 文档了解这些方法的详细信息。

Capybara 在请求规格中不受支持。使用 Capybara 的推荐方法是使用 功能规格

指定使用 Rails 集成方法管理小部件

给定一个名为 “spec/requests/widgetmanagementspec.rb” 的文件,其中包含

require "rails_helper"

RSpec.describe "Widget management", type: :request do

  it "creates a Widget and redirects to the Widget's page" do
    get "/widgets/new"
    expect(response).to render_template(:new)

    post "/widgets", :params => { :widget => {:name => "My Widget"} }

    expect(response).to redirect_to(assigns(:widget))
    follow_redirect!

    expect(response).to render_template(:show)
    expect(response.body).to include("Widget was successfully created.")
  end

  it "does not render a different template" do
    get "/widgets/new"
    expect(response).to_not render_template(:show)
  end
end

我运行 `rspec spec/requests/widget_management_spec.rb`

那么该示例应该通过。

请求 JSON 响应

给定一个名为 “spec/requests/widgetmanagementspec.rb” 的文件,其中包含

require "rails_helper"

RSpec.describe "Widget management", type: :request do
  it "creates a Widget" do
    headers = { "ACCEPT" => "application/json" }
    post "/widgets", :params => { :widget => {:name => "My Widget"} }, :headers => headers

    expect(response.content_type).to eq("application/json; charset=utf-8")
    expect(response).to have_http_status(:created)
  end
end

我运行 `rspec spec/requests/widget_management_spec.rb`

那么该示例应该通过。

提供 JSON 数据

给定一个名为 “spec/requests/widgetmanagementspec.rb” 的文件,其中包含

require "rails_helper"

RSpec.describe "Widget management", type: :request do

  it "creates a Widget and redirects to the Widget's page" do
    headers = { "CONTENT_TYPE" => "application/json" }
    post "/widgets", :params => '{ "widget": { "name":"My Widget" } }', :headers => headers
    expect(response).to redirect_to(assigns(:widget))
  end

end

我运行 `rspec spec/requests/widget_management_spec.rb`

那么该示例应该通过。

使用引擎路由助手

给定一个名为 “spec/requests/widgets_spec.rb” 的文件,其中包含

require "rails_helper"

# A very simple Rails engine
module MyEngine
  class Engine < ::Rails::Engine
    isolate_namespace MyEngine
  end

  class LinksController < ::ActionController::Base
    def index
      render plain: 'hit_engine_route'
    end
  end
end

MyEngine::Engine.routes.draw do
  resources :links, :only => [:index]
end

Rails.application.routes.draw do
  mount MyEngine::Engine => "/my_engine"
end

module MyEngine
  RSpec.describe "Links", type: :request do
    include Engine.routes.url_helpers

    it "redirects to a random widget" do
      get links_url
      expect(response.body).to eq('hit_engine_route')
    end
  end
end

我运行 `rspec spec`

那么该示例应该通过。

测试子域约束请求

给定一个名为 “spec/requests/widgets_spec.rb” 的文件,其中包含

require "rails_helper"

Rails.application.routes.draw do
  resources :widgets, constraints: { subdomain: "api" }
end

RSpec.describe "Widget management", type: :request do
  before { host! "api.example.com" }

  it "creates a Widget" do
    headers = { "ACCEPT" => "application/json" }
    post "/widgets", :params => { :widget => { :name => "My Widget" } }, :headers => headers

    expect(response.content_type).to start_with("application/json")
    expect(response).to have_http_status(:created)
  end
end

我运行 `rspec spec`

那么该示例应该通过。