我正在Rails和RSpec中编写控制器测试,从阅读ActionController::TestCase
的源代码看,它不可能将任意查询参数传递给控制器 - 只有路由参数。
要解决此限制,我目前正在使用with_routing
:
with_routing do |routes|
# this nonsense is necessary because
# Rails controller testing does not
# pass on query params, only routing params
routes.draw do
get '/users/confirmation/:confirmation_token' => 'user_confirmations#show'
root :to => 'root#index'
end
get :show, 'confirmation_token' => CONFIRMATION_TOKEN
end
正如您可能猜到的那样,我正在测试Devise的自定义Confirmations控制器。这意味着我正在使用现有的API,并且无法更改config/routes.rb
中实际映射的完成方式。
有更简洁的方法吗? get
支持的方式传递查询参数?
编辑: 正在进行其他事情。我在https://github.com/clacke/so_13866283中创建了一个最小的例子:
spec/controllers/receive_query_param_controller_spec.rb
describe ReceiveQueryParamController do
describe '#please' do
it 'receives query param, sets @my_param' do
get :please, :my_param => 'test_value'
assigns(:my_param).should eq 'test_value'
end
end
end
app/controllers/receive_query_param_controller.rb
class ReceiveQueryParamController < ApplicationController
def please
@my_param = params[:my_param]
end
end
config/routes.rb
So13866283::Application.routes.draw do
get '/receive_query_param/please' => 'receive_query_param#please'
end
这个测试通过了,所以我认为它是Devise,可以通过路由做一些时髦的事情。
编辑:
确定定义Devise路线的位置,并更新我的示例应用以匹配它。
So13866283::Application.routes.draw do
resource :receive_query_param, :only => [:show],
:controller => "receive_query_param"
end
...并且相应地更新规范和控制器以使用#show
。测试仍然通过,即params[:my_param]
填充get :show, :my_param => 'blah'
。所以,仍然有一个谜,为什么这不会发生在我的真实应用程序中。
答案 0 :(得分:3)
控制器测试不会路由。您正在对控制器进行单元测试 - 路由超出了其范围。
典型的控制器规范示例测试操作:
describe MyController do
it "is successful" do
get :index
response.status.should == 200
end
end
您可以通过将参数传递给get
来设置测试上下文,例如:
get :show, :id => 1
您可以在该哈希中传递查询参数。
如果您 想要测试路由,您可以编写路由规范或请求(集成)规范。
答案 1 :(得分:1)
你确定没有其他事情发生吗?我有一个Rails 3.0.x项目,并且正在传递参数..好吧..这是一个帖子..也许它与get有所不同,但这看起来很奇怪..
before { post :contact_us, :contact_us => {:email => 'joe@example.com',
:category => 'Category', :subject => 'Subject', :message => 'Message'} }
以上内容肯定在params
对象的控制器中使用。
答案 2 :(得分:1)
我现在正在这样做:
@request.env['QUERY_STRING'] = "confirmation_token=" # otherwise it's ignored
get :show, :confirmation_token => CONFIRMATION_TOKEN
......但它看起来很黑。
如果有人能给我一个干净利落的官方方式,我会很高兴。从我在#get
的源代码中看到的内容以及它所调用的一切来看,似乎没有其他任何方式,但我希望我忽略了一些东西。