将Rspec默认GET请求格式设置为JSON

Dra*_*kic 48 rspec ruby-on-rails functional-testing

我正在使用Rspec为我的控制器进行功能测试.我已将路由器中的默认响应格式设置为JSON,因此每个没有后缀的请求都将返回JSON.

现在在rspec中,当我尝试时,我得到一个错误(406)

get :index
Run Code Online (Sandbox Code Playgroud)

我需要去做

get :index, :format => :json
Run Code Online (Sandbox Code Playgroud)

现在因为我主要使用我的API支持JSON,所以必须为每个请求指定JSON格式是非常多余的.

我可以以某种方式将其设置为我的所有GET请求的默认值吗?(或所有要求)

Pra*_*oya 51

before :each do
  request.env["HTTP_ACCEPT"] = 'application/json'
end
Run Code Online (Sandbox Code Playgroud)

  • 新的Rspec 3语法会很复杂 (6认同)
  • 这在Rspec 3中不再起作用 (5认同)

kno*_*opx 25

把它放进去spec/support:

require 'active_support/concern'

module DefaultParams
  extend ActiveSupport::Concern

  def process_with_default_params(action, parameters, session, flash, method)
    process_without_default_params(action, default_params.merge(parameters || {}), session, flash, method)
  end

  included do
    let(:default_params) { {} }
    alias_method_chain :process, :default_params
  end
end

RSpec.configure do |config|
  config.include(DefaultParams, :type => :controller)
end
Run Code Online (Sandbox Code Playgroud)

然后简单地覆盖default_params:

describe FooController do
    let(:default_params) { {format: :json} }
    ...
end
Run Code Online (Sandbox Code Playgroud)


sch*_*jos 16

以下适用于我的rspec 3:

before :each do
  request.headers["accept"] = 'application/json'
end
Run Code Online (Sandbox Code Playgroud)

这套HTTP_ACCEPT.

  • 这适用于Rails 5.0.1 + RSpec 3.5.2 + JBuilder 2.6.0. (2认同)

Fra*_* Yu 11

这是一个解决方案

  1. 适用于请求规格,
  2. 适用于Rails 5和
  3. 不涉及Rails的私有API(如process).

这是RSpec配置:

module DefaultFormat
  extend ActiveSupport::Concern

  included do
    let(:default_format) { 'application/json' }
    prepend RequestHelpersCustomized
  end

  module RequestHelpersCustomized
    l = lambda do |path, **kwarg|
      kwarg[:headers] = {accept: default_format}.merge(kwarg[:headers] || {})
      super(path, **kwarg)
    end
    %w(get post patch put delete).each do |method|
      define_method(method, l)
    end
  end
end

RSpec.configure do |config|
  config.include DefaultFormat, type: :request
end
Run Code Online (Sandbox Code Playgroud)

验证

describe 'the response format', type: :request do
  it 'can be overridden in request' do
    get some_path, headers: {accept: 'text/plain'}
    expect(response.content_type).to eq('text/plain')
  end

  context 'with default format set as HTML' do
    let(:default_format) { 'text/html' }

    it 'is HTML in the context' do
      get some_path
      expect(response.content_type).to eq('text/html')
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

FWIW,可以放置RSpec配置:

  1. 直接进入spec/spec_helper.rb.这不是建议; 即使在测试库方法时,也会加载该文件lib/.

  2. 直接进入spec/rails_helper.rb.

  3. (我的最爱)在spec/support/default_format.rb和明确加载spec/rails_helper.rb

    require 'support/default_format'
    
    Run Code Online (Sandbox Code Playgroud)
  4. spec/support,并被加载

    Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
    
    Run Code Online (Sandbox Code Playgroud)

    加载所有文件spec/support.

这个解决方案的灵感来自knoopx的答案.他的解决方案不适用于请求规范,并且alias_method_chain已被弃用Module#prepend.


Dan*_*ohn 7

在RSpec 3中,您需要将JSON测试作为请求规范才能呈现视图.这是我使用的:

# spec/requests/companies_spec.rb
require 'rails_helper'

RSpec.describe "Companies", :type => :request do
  let(:valid_session) { {} }

  describe "JSON" do
    it "serves multiple companies as JSON" do
      FactoryGirl.create_list(:company, 3)
      get 'companies', { :format => :json }, valid_session
      expect(response.status).to be(200)
      expect(JSON.parse(response.body).length).to eq(3) 
    end

    it "serves JSON with correct name field" do
      company = FactoryGirl.create(:company, name: "Jane Doe")
      get 'companies/' + company.to_param, { :format => :json }, valid_session
      expect(response.status).to be(200)
      expect(JSON.parse(response.body)['name']).to eq("Jane Doe")
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

至于在所有测试中设置格式,我喜欢这个答案的方法:https://stackoverflow.com/a/14623960/1935918


zw9*_*963 6

也许您可以使用以下方法将第一个答案添加到spec / spec_helper或spec / rails_helper中:

config.before(:each) do
  request.env["HTTP_ACCEPT"] = 'application/json' if defined? request
end
Run Code Online (Sandbox Code Playgroud)

如果在模型测试(或任何不存在的请求方法上下文)中,则忽略此代码。它可以与rspec 3.1.7和rails 4.1.0一起使用,通常应该与所有rails 4版本一起使用。

  • 如果将其更改为config.before(:each,请输入::controller),则不会达到模型规格。 (3认同)