来自RSpec的Rails帖子"没有路由匹配"

时间:2014-04-28 20:48:06

标签: ruby-on-rails ruby rspec routing

我有路线定义

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

控制器

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

  def create
   # do some staff
  end
end

如果我使用RestConsole发送帖子请求 - 它的工作方式应该如此,但如果我尝试从RSpec测试发送帖子,如下所示 - 它会抛出异常。

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

错误消息:

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)>'

1 个答案:

答案 0 :(得分:2)

尝试:

post :create, user_data_to_post, format: :json

首先,post方法需要您传递给初始describe的控制器上的操作名称。由于您通过了路径,因此将整个路径视为操作名称,显然没有路由。

其次,post方法签名位于行post(action_name, raw_post_data(assigned only if string), params=nil, session=nil, flash=nil)中(事实上它是post(action_name, *args),但这就是处理这些args的方法。正如你想要修改标题,你需要直接根据请求执行此操作:

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

或传递format: :json和params