1

我在从控制器渲染 .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',我会收到有关“缺少模板 api_docs/index”的错误。同样,如果我必须传递文件名,那么我必须提供确切的目录就更糟了——Rails 应该知道我的 ApiDocsController 模板位于 api_docs 目录中。

如果我有render fileor 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),如果 I raise response.body,它是一个空字符串。如果我render json: {'apiVersion' => '1.0'}.to_json在控制器中这样做,那么测试就可以通过了。

那么,当我转到 /api_docs(而不必放在 URL 的末尾)时,如何始终呈现 JSON 模板.json,并且以一种在浏览器和我的 RSpec 测试中都有效的方式?我可以渲染模板而不必进行一些长时间的render调用来传递视图的完整路径吗?

4

2 回答 2

0

实际上,由于您已经respond_to :json在控制器中使用,您可以只使用一种render方法来选择您的模板,并且您可能知道,如果模板与控制器方法具有相同的名称,您应该能够抑制整个render方法。

如果你只是删除render线,结果是什么?

于 2013-09-04T18:38:55.047 回答
0

我的部分解决方案基于对另一个问题的回答:添加defaults: {format: :json}到我的路由文件让我可以转到 /api_docs 并在操作为def index ; endno时查看 JSON render。RSpec 测试仍然失败。我的路线文件中的完整行:resources :api_docs, only: [:index], defaults: {format: :json}.

感谢这个有同样问题的人和他的要点,我添加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
于 2013-09-04T18:42:01.767 回答