我有最糟糕的时间从我的控制器渲染.json.erb文件,同时能够使用RSpec进行测试。我有api_docs / index.json.erb和以下控制器:
class ApiDocsController < ApplicationController
respond_to :json
def index
render file: 'api_docs/index.json.erb', content_type: 'application/json'
end
end
显式render file
行似乎没必要,但如果我不这样做或render template: 'api_docs/index.json.erb'
,那么我会收到有关“Missing template api_docs / index”的错误。同样,如果我必须传递文件名,那就更糟糕了,我必须提供确切的目录--Rails应该知道我的ApiDocsController模板存在于api_docs目录中。
如果我有render file
或render template
,那么我可以访问该页面并按预期获取index.json.erb文件的JSON内容。但是,这个RSpec测试失败了:
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
JSON.parse(response.body)
行失败,如果我raise response.body
,则为空字符串。如果我在控制器中执行render json: {'apiVersion' => '1.0'}.to_json
,则测试通过就好了。
那么,当我转到/ api_docs时(无需将.json
放在URL的末尾),我怎样才能始终呈现JSON模板,并且在浏览器和我的浏览器中都可以使用RSpec测试?我是否可以渲染模板而无需进行长render
次调用,我可以在其中传递视图的完整路径?
答案 0 :(得分:0)
实际上,由于您已经在控制器中使用respond_to :json
,因此您只需使用render
方法来选择模板,并且您可能知道,如果模板具有相同的控制器名称你应该能够抑制整个render
方法的方法。
如果您只删除render
行,结果是什么?
答案 1 :(得分:0)
我的部分解决方案基于this answer另一个问题:将defaults: {format: :json}
添加到我的路径文件中,让我转到/ api_docs并在动作仅为def index ; end
时查看JSON没有render
。但RSpec测试仍然失败。我的路线文件中的完整行:resources :api_docs, only: [:index], defaults: {format: :json}
。
感谢this guy遇到同样的问题和his gist,我将render_views
添加到了我的describe
块,并让我的测试通过了:
describe ApiDocsController do
render_views
...
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