如何在RSpec中使用xhr发送含"params"字符串键的JSON请求?
解决Rails 4.2 XHR测试中传递字符串类型
params参数的问题 我之前也遇到过类似的坑,咱们来拆解下问题根源和解决办法:
问题原因
在Rails 4.2的测试框架里,xhr(也就是xml_http_request)方法会把你传入的顶级参数Hash里的params键当作路由系统的配置选项(用来合并路由参数),而不是普通的请求参数。当你传入字符串'some,key'时,路由系统的merge!方法尝试把字符串和路由参数Hash合并,自然就报错了。
解决方案
下面是几种不需要修改后端代码就能解决的办法,按推荐程度排序:
方案1:直接设置请求体(最推荐)
模拟真实HTTP请求的方式,把params=some,key作为请求体发送,这样params会被当作普通表单参数解析,完全绕过路由系统对params键的特殊处理。
it 'send request' do do_login :superguru # 先调用xhr设置路由参数和XHR标识,不传递params参数 xhr :post, :create, locale: :en, customer_id: customer.id # 表单编码格式的请求体(对应后端默认的表单解析) request.raw_post = 'params=some%2Ckey' # 如果是JSON接口,替换成下面两行: # request.raw_post = '{ "params": "some,key" }' # request.content_type = 'application/json' # 这里添加你的断言逻辑,比如: # expect(response).to have_http_status(:success) end
方案2:手动构造请求(更灵活)
直接使用process方法手动搭建请求,精准控制每个参数的作用域,避免路由系统误处理params键。
it 'send request' do do_login :superguru setup_controller_request_and_response # 标记为XHR请求 request.xhr = true # 设置路由参数和请求方法 process :create, method: :post, params: { locale: :en, customer_id: customer.id } # 添加需要的字符串类型params请求参数 request.params[:params] = 'some,key' # 执行控制器动作 controller.send(:process, :create) # 这里添加断言逻辑 end
方案3:嵌套参数(需后端配合)
如果后端代码可以调整,你可以把params字符串嵌套在另一个键下,避免顶级params被路由系统拦截:
it 'send request' do do_login :superguru xhr :post, :create, locale: :en, customer_id: customer.id, data: { params: 'some,key' } end
之后后端通过params[:data][:params]获取值即可,但这个方案依赖后端代码调整,如果你无法修改后端就不适用。
内容的提问来源于stack exchange,提问作者dom
相关产品推荐
相关产品推荐

