可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
If your controller action looks like this:
respond_to do |format|
format.html { raise 'Unsupported' }
format.js # index.js.erb
end
and your functional test looks like this:
test "javascript response..." do
get :index
end
it will execute the HTML branch of the respond_to block.
If you try this:
test "javascript response..." do
get 'index.js'
end
it executes the view (index.js.erb) withOUT running the controller action!
回答1:
Pass in a :format
with your normal params to trigger a response in that format.
get :index, :format => 'js'
No need to mess with your request headers.
回答2:
with rspec:
it "should render js" do
xhr :get, 'index'
response.content_type.should == Mime::JS
end
and in your controller action:
respond_to do |format|
format.js
end
回答3:
Set the accepted content type to the type you want:
@request.accept = "text/javascript"
Combine this with your get :index
test and it will make the appropriate call to the controller.
回答4:
Use this before request:
@request.env['HTTP_ACCEPT'] = 'text/javascript'
回答5:
These three seem to be equivalent:
get :index, :format => 'js'
@request.env['HTTP_ACCEPT'] = 'text/javascript'
@request.accept = "text/javascript"
They cause the controller to use a js template (e.g. index.js.erb)
Whereas simulating an XHR request (e.g. to get a HTML snippet) you can use this:
@request.env['HTTP_X_REQUESTED_WITH'] = "XMLHttpRequest"
This means request.xhr? will return true.
Note that, when simulating XHR, I had to specify the expected format or I got an error:
get :index, format: "html"
Tested on Rails 3.0.3.
I got the latter from the Rails source, here: https://github.com/rails/rails/blob/6c8982fa137421eebdc55560d5ebd52703b65c65/actionpack/lib/action_dispatch/http/request.rb#L160
回答6:
RSpec 3.7 and Rails 5.x solution:
A few of these answers were a little outdated in my case so I decided to provide an answer for those running Rails 5 and RSpec 3.7:
it "should render js" do
get :index, xhr: true
expect(response.content_type).to eq('text/javascript')
end
Very similar to Steve's answer with a few adjustments. The first being xhr
is passed as a boolean key/pair. Second is I now use expect
due to should
receiving deprecation warnings if used. Comparing the content_type
of the response to be equal to text/javascript
worked for me.
回答7:
Use code like this for parameters and user id, etc., notice that format option is in the same hash of other parameters like id and nested_attributes.
put :update, {id: record.id, nested_attributes: {id: 1, name: "John"}, format: :js}, user.id
回答8:
Many of the above answers are outdated.
The correct way to do it in RSpec 3+ is post some_path, xhr: true
.
Deprecation warning straight from RSpec itself, when attempting to use xhr :post, "some_path"
:
DEPRECATION WARNING: `xhr` and `xml_http_request` are deprecated and will be removed in Rails 5.1.
Switch to e.g. `post comments_path, params: { comment: { body: 'Honey bunny' } }, xhr: true`.
Also, xhr :post, "some_path"
results in some funky errors that doesn't happen with post some_path, xhr: true
.