복붙노트

[RUBY-ON-RAILS] JSON으로 설정 RSpec에 기본 GET 요청 형식

RUBY-ON-RAILS

JSON으로 설정 RSpec에 기본 GET 요청 형식

나는 RSpec에 내 컨트롤러 기능 테스트를하고있는 중이 야. 접미사없이 모든 요청은 JSON을 반환 그래서 나는, JSON에 내 라우터에 내 기본 응답 형식을 설정했습니다.

내가하려고 할 때 이제 RSpec에, 나는 (406) 오류가 발생합니다

get :index

난 할 필요가있어

get :index, :format => :json

나는 주로 내 API와 JSON을 지원하고 있기 때문에 지금, 그것은 모든 요청에 ​​대한 JSON 형식을 지정하는 데 매우 중복됩니다.

난 어떻게 든 내 모든 GET 요청에 대해 기본값을 설정할 수 있습니까? (또는 모든 요청)

해결법

  1. ==============================

    1.

    before :each do
      request.env["HTTP_ACCEPT"] = 'application/json'
    end
    
  2. ==============================

    2.사양 / 지원이를 넣어 :

    사양 / 지원이를 넣어 :

    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
    

    그리고 단순히 default_params를 오버라이드 (override) :

    describe FooController do
        let(:default_params) { {format: :json} }
        ...
    end
    
  3. ==============================

    3.RSpec에 3 나를 위해 다음 작품 :

    RSpec에 3 나를 위해 다음 작품 :

    before :each do
      request.headers["accept"] = 'application/json'
    end
    

    이 HTTP_ACCEPT 설정합니다.

  4. ==============================

    4.다음 용액 즉

    다음 용액 즉

    여기에 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
    

    확인

    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
    

    FWIW는 RSpec에 구성을 배치 할 수 있습니다 :

    이 솔루션은 knoopx의 대답에 의해 영감을받은 것입니다. 그의 해결책은 요구 사양이 작동하지 않으며, alias_method_chain은 모듈 번호의 앞에 추가 찬성 사용되지 않습니다.

  5. ==============================

    5.RSpec에 3에서는 JSON 테스트는 뷰 렌더링이 있기 위하여 요구 사양이 될 수 있도록 필요가있다. 여기에 내가 무엇을 사용 :

    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
    

    모든 테스트의 형식을 설정, 나는이 다른 대답의 접근 방식을 좋아한다 : https://stackoverflow.com/a/14623960/1935918

  6. ==============================

    6.아마 당신은 사양 / spec_helper 또는 사양 /이와 rails_helper에 첫 번째 대답을 추가 할 수 있습니다 :

    아마 당신은 사양 / spec_helper 또는 사양 /이와 rails_helper에 첫 번째 대답을 추가 할 수 있습니다 :

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

    모델 테스트 (또는하지 요청 방법 컨텍스트 존재) 경우,이 코드는 무시합니다. 그것은 RSpec에 3.1.7로 근무 4.1.0 레일 그것은 4 버전은 일반적으로 모든 레일과 협력해야한다.

  7. ==============================

    7.레일 5 RSpec에 3.5을 실행 나는이 작업을 수행하기 위해 헤더를 설정했다.

    레일 5 RSpec에 3.5을 실행 나는이 작업을 수행하기 위해 헤더를 설정했다.

    post '/users', {'body' => 'params'}, {'ACCEPT' => 'application/json'}
    

    티는 같은 문서의 외모에 무엇을 예 일치 :

    require "rails_helper"
    
    RSpec.describe "Widget management", :type => :request do
      it "creates a Widget" do
        headers = {
          "ACCEPT" => "application/json",     # This is what Rails 4 accepts
          "HTTP_ACCEPT" => "application/json" # This is what Rails 3 accepts
        }
        post "/widgets", { :widget => {:name => "My Widget"} }, headers
    
        expect(response.content_type).to eq("application/json")
        expect(response).to have_http_status(:created)
      end
    end
    
  8. ==============================

    8.이 같은 JSON : 요청과 작업 ActionDispatch :: 통합 :: 세션과에 매개 변수로 설정 기본에 #process 메소드를 오버라이드 (override) 할 내가 찾은 가장 쉬운 방법입니다 된 테스트 그 사람을 위해 :

    이 같은 JSON : 요청과 작업 ActionDispatch :: 통합 :: 세션과에 매개 변수로 설정 기본에 #process 메소드를 오버라이드 (override) 할 내가 찾은 가장 쉬운 방법입니다 된 테스트 그 사람을 위해 :

    module DefaultAsForProcess
      def process(method, path, params: nil, headers: nil, env: nil, xhr: false, as: :json)
        super
      end
    end
    
    ActionDispatch::Integration::Session.prepend(DefaultAsForProcess)
    
  9. ==============================

    9.RSpec에 문서 당, 지원 방법은 헤더를 통해 :

    RSpec에 문서 당, 지원 방법은 헤더를 통해 :

    require "rails_helper"
    
    RSpec.describe "Widget management", :type => :request do
    
      it "creates a Widget" do
        headers = {
          "ACCEPT" => "application/json",      # This is what Rails 4 and 5 accepts
          "HTTP_ACCEPT" => "application/json", # This is what Rails 3 accepts
        }
        post "/widgets", :params => { :widget => {:name => "My Widget"} }, :headers => headers
    
        expect(response.content_type).to eq("application/json")
        expect(response).to have_http_status(:created)
      end
    
    end
    
  10. ==============================

    10.왜 RSpec에의 방법은, "POST", "풋", 보석 (또는 외부 레일)의 컨트롤러 사양의 작업을 "삭제"를 "GET"합니까?

    왜 RSpec에의 방법은, "POST", "풋", 보석 (또는 외부 레일)의 컨트롤러 사양의 작업을 "삭제"를 "GET"합니까?

    이 질문에 기반으로, 당신은 https://github.com/rails/rails/blob/32395899d7c97f69b508b7d7f9b7711f28586679/actionpack/lib/action_controller/test_case.rb에서 ActionController :: TestCase에에서 재정의 과정 ()을 시도 할 수 있습니다.

    여기 내 해결하지만입니다.

    describe FooController do
        let(:defaults) { {format: :json} }
    
        context 'GET index' do
            let(:params) { defaults }
            before :each do
                get :index, params
            end
    
            # ...
        end
    
        context 'POST create' do
            let(:params) { defaults.merge({ name: 'bar' }) }
            before :each do
                post :create, params
            end
    
            # ...
        end
    end
    
  11. from https://stackoverflow.com/questions/11022839/set-rspec-default-get-request-format-to-json by cc-by-sa and MIT license