I'm having the worst time rendering a .json.erb file from my controller while being able to test it with RSpec. I have api_docs/index.json.erb and the following controller:
class ApiDocsController < ApplicationController
respond_to :json
def index
render file: 'api_docs/index.json.erb', content_type: 'application/json'
end
end
The explicit render file
line seems unnecessary, but if I don't do that or render template: 'api_docs/index.json.erb'
, then I get an error about "Missing template api_docs/index". Likewise if I do have to pass the file name, it sucks even more that I have to give the exact directory--Rails should know that my ApiDocsController templates live in the api_docs directory.
If I have render file
or render template
, then I can visit the page and get the JSON contents of my index.json.erb file, as expected. However, this RSpec test fails:
let(:get_index) { ->{ get :index } }
...
describe 'JSON response' do
subject {
get_index.call
JSON.parse(response.body)
}
it 'includes the API version' do
subject['apiVersion'].should_not be_nil
end
end
It fails on the JSON.parse(response.body)
line and if I raise response.body
, it's an empty string. If I do render json: {'apiVersion' => '1.0'}.to_json
in the controller, then the test passes just fine.
So, how can I always render the JSON template when I go to /api_docs (without having to put .json
at the end of the URL), and in a way that works both in the browser and in my RSpec test? And can I render the template without having to have some long render
call in which I pass the full path of the view?