A bit of background to clarify the situation: although the request cannot be both GET and POST, nothing stops using it as query strings and body shape data when using POST. You can even have a POST with all parameters in the query string and an empty body , although this sounds pretty unusual.
Rails supports this script, and you can easily submit a form using a POST request and still have the request in the form action. The request will be available with the request.GET hash (which is the query_string alias), while the POST body with the request.POST hash parameter (the request_parameters alias). The params hash is actually built from combined GET and POST hashes .
However, from my research, it seems that Rails does not support passing request strings in POST requests in functional controller tests . Although I could not find anything about this in any documentation or among the known issues on github , the source code is pretty clear. In the following text, I assume that you are using Rails 4.
Why it does not work
The problem with functional controller checks is that they do not use real requests / responses, but mimic the HTTP hash code: the request is tricked, its parameters are filled in the appropriate places, and this controller action is simply called the normal ruby ββmethod. All this is done in the action_controller/test_case .
As it turned out, this simulation does not work in your particular case for two reasons:
The parameters passed when the test was run are always passed either to request_parameters , i.e. hash request.POST when using a POST request or to query_string (i.e. request.GET ) for GET test requests. It is not possible to set both of these hashes during the same test run.
It really makes sense since GET , POST , etc. helpers in functional tests accept only one hash of parameters, so the internal test code cannot know how to split them into two hashes.
It is true that you can request a query before running the test using the @request variable, but only to a certain extent can you set headers, for example. But you cannot set the internal attributes of the request because they are processed during the test run. This recycling is done here , and it resets all the internal variables of the request object and the base rack request object. Therefore, if you try to configure GET request parameters, such as @request.GET[:api_key] = 'my key' , this will have no effect, since the internal variables representing this hash will be erased during disposal.
Solutions / Workarounds
Give up functional testing and choose integration tests instead . Integration tests allow you to set the environment variables of the rack separately from the main parameters. The following integration test passes the variable ente tv2 query_string , in addition to the usual body post parameters, and should work flawlessly:
class CollectionsTest < ActionDispatch::IntegrationTest test 'foo' do post collections_path, { collection: { name: 'New Collection' } }, { "QUERY_STRING" => "api_key=my_api_key" }
You can use most functions from functional tests in your integration tests. For instance. you can check the assigned instance variables in the controller with the assigns hash.
The transition argument is also supported by the fact that Rails 5 will refuse functional controller tests in favor of integration testing and since Rails 5.1 supports these functional tests, they will be moved to a separate stone.
Try Rails 5: although the functional tests will be deprecated, its source code seems to have been heavily rewritten in the master rail and for example reusing the query is no longer used. Therefore, you can try and try to set the internal query variables during the installation of the test. I have not tested it though.
Of course, you can always try to disable a functional test so that it supports separate parameters for the query_string and request_parameters hashes, which must be defined in the tests.
I would go along the route of integration tests :).
source share