子域上的rspec POST api测试

时间:2015-10-12 15:02:55

标签: ruby-on-rails rspec

my routes.rb

  constraints subdomain: 'api' do
    namespace :api, path: '/' do
      scope '/v1' do
        scope '/things' do
          post '/', to: 'things#create'
        end
      end
    end
  end

我现在要做的就是在rspec控制器测试中测试POST方法:

it 'should create things on a post request' do
  post 'create',
   { thing: { foo: bar }.to_json
  assert_equal 204, response.status
end

我最终得到了这个:

 Failure/Error: post 'create',
 ActionController::UrlGenerationError:
 No route matches {:action=>"create", :controller=>"api/things"}

我想这与api子域约束有关,所以我一直试图在rspec中初始化子域:

request.host = 'api.mydevdomain.dev'

我还尝试将整个网址包含在帖子请求中,但没有成功。

如何在上面的示例中为rspec设置子域?这是错误的原因还是有其他原因?

1 个答案:

答案 0 :(得分:1)

尝试设置这样的路线:

Rails.application.routes.draw do
  constraints subdomain: 'api' do
    scope module: 'api', as: 'api' do
      namespace 'v1' do
        resources :things
      end
    end
  end
end

为了设置版本化的api,您应该将每个控制器放在"版本模块中#34;。所以你的Api :: ThingsController应该是:

# controllers/api/v1/things_controller.rb
class Api::V1::ThingsController
  # ...

  # POST /api/v1/things
  def create
  end
end

然后你可以用以下方法测试它:

RSpec.describe Api::V1::ThingsController, type: :controller do
  describe "POST #create" do
    it "returns http success" do
      post :create, { thing: { foo: bar }, format: :json}
      expect(response).to have_http_status :created
      expect(response.headers['location']).to eq thing_path(Thing.last)
    end
  end
end

但是,如果您真的想测试路由层,请改用request spec。这就像一个功能规格,但没有Capybara的开销。