Rails功能测试:在POST请求中发送URL查询参数 [英] Rails functional test: sending URL query parameters in POST request

查看:128
本文介绍了Rails功能测试:在POST请求中发送URL查询参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在这样的Rails功能测试中发送POST请求:

I'm sending a POST request in a Rails functional test like this:

post :create, collection: { name: 'New Collection' }

collection被发送为JSON编码的表单数据,符合预期.

collection gets sent as JSON-encoded form data, as expected.

我不知道如何在URL中添加查询. 文档说,我可以访问请求对象并在发送请求之前对其进行修改.所以我尝试了这个:

What I can't figure out is how to add a query to the URL. The documentation says that I can access the request object and modify it before it gets sent. So I tried this:

@request.GET[:api_key] = 'my key'
post :create, collection: { name: 'New Collection' }

但是,:api_key永远不会出现在服务器上的request.GET哈希中. (不过,当我通过另一个HTTP客户端发送它时也是如此.)

But, :api_key never appears in the request.GET hash on the server. (It does when I send it though another HTTP client, though.)

推荐答案

首先要弄清楚背景:尽管请求不能同时是GET和POST,但是有中包含所有参数的POST,并留空身体,尽管听起来很不寻常.

A little background first to clarify things: although a request cannot be both GET and POST at the same time, there is nothing stopping you from using both the query string and body form data when using POST. You can even have a POST with all parameters in the query string and an empty body, though this sounds quite unusual.

Rails支持这种情况,实际上,您可以轻松地使用POST请求发送表单,并且仍然可以对表单进行查询.该查询将通过 request.GET哈希(这是query_string的别名),而POST正文使用组合的POST哈希.

Rails supports this scenario and indeed you can easily send a form using a POST request and still have query in the form's action. The query will be accessible with request.GET hash (which is an alias of query_string), while the POST body params with the request.POST hash (an alias of request_parameters). The params hash is actually constructed from the combined GET and POST hashes.

但是,从我的研究看来, Rails不支持在功能控制器测试中的POST请求中传递查询字符串.尽管我在任何文档中或

However, from my research it seems that Rails does not support passing query string in POST requests in functional controller tests. Although I could not find anything regarding this in any documentation or among known issues on github, the source code is quite clear. In the following text, I'm assuming that you use Rails 4.

功能性控制器测试的问题在于它们不使用实际的请求/响应,而是模拟HTTP握手:模拟请求,将其参数填充在适当的位置,并且将给定的控制器操作简单地称为正常操作红宝石方法.所有这些都是在 .

The problem with functional controller tests is that they don't use real requests / responses but they simulate the HTTP handshake: the request is mocked up, its parameters filled in appropriate places and the given controller action is simply called as a normal ruby method. All of this is done in the action_controller/test_case classes.

事实证明,由于以下两个原因,该模拟不适用于您的特定情况:

As it turns out, this simulation is not working in your particular case, due to two reasons:

  1. 运行测试时传递的参数总是

  1. The parameters passed in when running the test are always handed over either to the request_parameters, i.e. the request.POST hash when using a post request or to the query_string (i.e. request.GET) for get test requests. There is no way for both of these hashes to be set during a single test run.

这实际上与getpost等类似.在功能测试中,辅助函数仅接受一个参数散列,因此内部测试代码无法知道如何将它们分为两个散列.

This actually makes some sense as the get, post, etc. helpers in functional tests accept only a single hash of params so the internal test code cannot know how to separate them into the two hashes.

的确可以在使用@request变量运行测试之前设置请求,但是例如,可以在一定程度上设置标头.但是您不能设置请求的内部属性,因为它们在测试运行期间被回收.回收是在此处完成的a>,它将重置请求对象和基础机架请求对象的所有内部变量.因此,如果尝试设置像@request.GET[:api_key] = 'my key'这样的请求GET参数,则该参数将无效,因为代表该哈希的内部变量将在回收期间被擦除.

It is true that one can set up the request before running the test using the @request variable, but only to a certain extent, you can set headers, for example. But you cannot set internal attributes of the request, because they are recycled during the test run. The recycling is done here and it resets all internal variables of the request object and the underlying rack request object. So if you try to set up the request GET parameters like this @request.GET[:api_key] = 'my key', it won't have any effect as the internal variables representing this hash will get wiped during recycling.

解决方案/解决方法

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆