【问题标题】:Specify URL parameters in Rails integration test / RSpec request spec在 Rails 集成测试/RSpec 请求规范中指定 URL 参数
【发布时间】:2017-07-13 09:11:49
【问题描述】:

我正在尝试为我正在构建的 Rails 应用程序编写请求规范,但文档很少(或者我还没有找到合适的文档)。

我有一个带有大多数常用 API 端点的 companies 资源:

# Routes -------------------------------------------------------------------
#    companies GET    /companies(.:format)          companies#index
#              POST   /companies(.:format)          companies#create
#  new_company GET    /companies/new(.:format)      companies#new
# edit_company GET    /companies/:id/edit(.:format) companies#edit
#      company GET    /companies/:id(.:format)      companies#show
#              DELETE /companies/:id(.:format)      companies#destroy
#              PATCH  /companies/:id(.:format)      companies#update

我希望我的规范表明,如果您在未登录时点击这些端点,它们会将您重定向到登录页面。对于前三个端点(没有:id 参数的端点),这很简单:

RSpec.describe 'Companies Endpoints', type: :request do    
  context 'with anonymous user' do
    it 'always redirects to sign-in page' do
      get '/companies'
      expect(response).to redirect_to(new_user_session_path)

      post '/companies'
      expect(response).to redirect_to(new_user_session_path)

      get '/companies/new'
      expect(response).to redirect_to(new_user_session_path)
  end
end

当端点包含 URL 参数 (get '/companies/:id/edit') 时,请求的语法是什么?到目前为止,这是我想出的:

RSpec.describe 'Companies Endpoints', type: :request do
  let :company { FactoryGirl.create(:company) }  # NOTE: this is new

  context 'with anonymous user' do
    it 'always redirects to sign-in page' do
      ...

      get "/companies/#{company.id}/edit"        # `company` is from the factory above
      expect(response).to redirect_to(new_user_session_path)

      ...
    end
  end

但我想知道这是否是“正确”的方式。

具体来说,the request spec scenarios on relishapp.com 显示使用 params 选项哈希作为 POST 请求的一部分,我想知道这个选项哈希是否也适用于 URL 参数?

RSpec.describe "Widget management", :type => :request do
  it "creates a Widget and redirects to the Widget's page" do
    post "/widgets", :params => { :widget => {:name => "My Widget"} }
    ...

【问题讨论】:

  • 你有没有发现如何做到这一点?我有确切的问题,但没有办法解决。

标签: ruby-on-rails rspec integration-testing


【解决方案1】:

您不需要在请求方法中指定整个 URL。 Rspec 提供了一种更短的方法,如下所述

RSpec.describe 'Companies Endpoints', type: :request do
  let :company { FactoryGirl.create(:company) }  # NOTE: this is new

  context 'with anonymous user' do
    it 'always redirects to sign-in page' do
      ...

      get :edit, { id: company.id }        # In this hash you can send any paramter, this will end up becoming your params for the request
      expect(response).to redirect_to(new_user_session_path)

      ...
    end
  end
end

也可以用以下方式重写您上面提到的 (post, new, index) 请求-

get :index
expect(response).to redirect_to(new_user_session_path)

post :create
expect(response).to redirect_to(new_user_session_path)

get :new
expect(response).to redirect_to(new_user_session_path)

【讨论】:

  • 我的理解是请求规范应该定义响应 HTTP 请求例如 <VERB> <ENDPOINT>),而不是控制器操作。这看起来更适合控制器规范?
  • @RyanLue 请关注此relishapp.com/rspec/rspec-rails/docs/controller-specs 它准确地展示了编写 rpecs 的最佳方式。干杯
  • 从 RSpec 3.5 开始,controller specs are discouraged in favor of request specs。直接从马嘴里说:“我们可以给开发 Rails 应用程序的人最好的建议是编写请求规范而不是控制器规范。我会考虑在 2017 年编写一个新的控制器规范来成为一种气味……”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-25
相关资源
最近更新 更多