4

Writing specs for a json api the routes are defaulted to only accept json requests like so:

Rails.application.routes.draw do
  namespace :api, default: { format: 'json' } do
    namespace :v1 do
      resources :users, only: [:create]
    end
  end
end

I keep getting the following error:

Failure/Error: post :create, json
ActionController::UrlGenerationError:
  No route matches {:action=>"create", :company_name=>"Wilderman, Casper and Medhurst", :controller=>"api/v1/users", :email=>"lillie_prohaska@example.com", :password=>"difdcbum5q", :username=>"gielle"}

Traditionally to get around this error I have set the CONTENT_TYPE and the HTTP_ACCEPT on the request so that it will pass the json formatting requirement.

My specs are written like so:

describe Api::V1::UsersController do

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

  describe "POST#create" do
    context "with valid attirbutes" do
      let(:json) { attributes_for(:user) }

      it "creates a new user" do
        expect{ post :create, json }.to change{ User.count }.by(1)
      end

      it "returns status code 200" do
        post :create, json
        expect(response.status).to be(200)
      end

      it "should contain an appropriate json response" do
        post :create, json
        user = User.last
        json_response = { 
          "success" => true, 
          "id" => user.id.to_s, 
          "auth_token" => user.auth_token 
        }
        expect(JSON.parse(response.body)).to eq (json_response)
      end
    end
  end
end

I have also tried adding a hash with { format: 'json' } which has also failed me.

According to the comments on the accepted answer for the question below setting the request environment headers will no longer work with rspec 3:

Set Rspec default GET request format to JSON

How would this be achieved in rspec 3 in Rails 4.1.1?

Thanks!

Community
  • 1
  • 1
  • You appear to be asking about setting the `Accept:` header of the request (which constrains the `Content-Type:` of the response), not the `Content-Type:` of the request itself. I've altered the title to reflect that. – Peeja Nov 10 '14 at 22:57

1 Answers1

1

Here is how I do it over here:

  [:xml, :json].each do |format|

    describe "with #{format} requests" do
      let(:api_request) { { :format => format } }
      describe "GET 'index'" do
          before :each do
            api_request.merge attributes_for(:user)
          end
          it 'returns HTTP success' do
            get :index, api_request
            expect(response).to be_success
          end
      end
    end
muichkine
  • 2,890
  • 2
  • 26
  • 36