防止控制器规范中的参数编码

时间:2015-05-13 12:46:49

标签: ruby-on-rails-4 rspec urlencode

我正在尝试为包含正斜杠的参数编写(失败的)控制器规范:

# products_controller_spec.rb 
it "accepts parameters with a forward slash" do
  get :show, id: 'foo/bar'
  expect(response).to be_success
  expect(response).to render_template('show')
end

这应该失败,因为'/ products / foo / bar'没有匹配的路由:

# routes.rb
resources :products, only: [:index, :show]

然而,它通过了,因为参数foo/bar在请求进入控制器之前进行了URL编码:

# products_controller.rb
def show
  Rails.logger.debug(request.env['PATH_INFO'])
end

test.log

中产生此结果
I, [2015-05-13T13:33:16.410943 #12962]  INFO -- : Processing by ProductsController#show as HTML
I, [2015-05-13T13:33:16.411029 #12962]  INFO -- :   Parameters: {"id"=>"foo/bar"}
...
D, [2015-05-13T13:33:16.412717 #12962] DEBUG -- : /products/foo%2Fbar/
I, [2015-05-13T13:33:16.413885 #12962]  INFO -- : Completed 200 OK in 3ms (Views: 0.9ms | ActiveRecord: 0.2ms)

请注意原始请求中的网址编码%2F而不是/。如果没有截断请求对象,如何在不为它编码请求参数的情况下发出rspec get请求?

1 个答案:

答案 0 :(得分:2)

您似乎真正想要测试的是,/products/foo/barProductsController作为"foo/bar"参数路由到id的展示操作

在幕后,rspec-rails控制器测试使用ActionController::TestCase,它提供assert_routing断言。在rspec-rails中,您可以将此断言与#route_to期望一起使用,如下所示:

expect(get: "/products/foo/bar").to route_to(controller: "products", action: "show", id: "foo/bar")