Andrew Kovalenko
Andrew Kovalenko

Reputation: 6710

Rails post from RSpec throws "no route matches"

I have route definition

post '/session/create' => 'sessions#create', as: 'create_session'

controller

class SessionsController < ApplicationController
  respond_to :json
  skip_before_filter :verify_authenticity_token, :only => :create

  def create
   # do some staff
  end
end

If I send post request using RestConsole - it works like it should, but if I try to send post from RSpec test like below - it throws exception.

require 'spec_helper'

describe SessionsController do
  let(:user_data_to_post) { FactoryGirl.attributes_for :user }

  let(:user) do
    mock_model User
  end

  describe 'create new session should be successful' do 
    before do 
      post(create_session_path, user_data_to_post.to_json,
          {'HTTP_CONTENT_TYPE' => 'application/json'})
    end

    it "should call search_by_email of User model" do
      User.should_recive(:search_by_email).with(user_data_to_post[:email])
    end
  end
end

error message:

Failure/Error: post(create_session_path, user_data_to_post.to_json,
ActionController::UrlGenerationError:
   No route matches {:HTTP_CONTENT_TYPE=>"application/json", :controller=>"sessions",     :action=>"/session/create"}
 # ./spec/controllers/sessions_controller_spec.rb:13:in `block (3 levels) in <top (required)>'

Upvotes: 2

Views: 776

Answers (1)

BroiSatse
BroiSatse

Reputation: 44675

Try:

post :create, user_data_to_post, format: :json

Firstly, post method expects the name of the action on the controller you passed to initial describe. Since you passed the path instead, it was treating the whole path as an action name, which obviously was not routed.

Secondly, post method signature is sth in line post(action_name, raw_post_data(assigned only if string), params=nil, session=nil, flash=nil) (in fact it is post(action_name, *args) but this is how those args are being processed. Sine you wanted to modify headers, you need to do this directly on a request:

@request['HTTP_CONTENT_TYPE'] = 'application/json'

or to pass format: :json along with params

Upvotes: 2

Related Questions