如何验证控制器测试中的json响应?

时间:2016-12-01 06:57:52

标签: ruby-on-rails rspec

我有一个只返回json的rails控制器

def index
  if params[:filtered] = 'someValue'
    @json = Model.where(some_conditions).to_json 
  else
    @json = Model.where(some_other_conditions).to_json 
  end
  render json: @json
end

测试操作返回预期的@json对象的正确方法是什么?

我尝试了以下

describe "GET #index" do  
  before :each do
    get :index, filtered: 'someValue'
  end
  it { expect( response.body ).to eq 'my expected response' }
end

但我得到了

Failure/Error: it { expect( response.body ).to eq 'my expected response' }
expected: 'my expected response'
got: "[]"

我无法确定底层控制器是否存在问题,或者我是否只是编写了一个错误的测试。

response.body是获取json有效负载的正确方法吗?

帮助表示感谢!

1 个答案:

答案 0 :(得分:4)

你的控制器和规格都有些偏离。

  

您无需在要渲染的对象上调用to_json。   如果您使用:json选项,渲染会自动调用to_json   对你而言   http://guides.rubyonrails.org/layouts_and_rendering.html

您的规范为您提供"[]"的原因是Model.where(some_conditions)正在返回一个空集合。空集合在JSON中呈现为空数组。

示波器无法正常工作或您的测试设置存在缺陷。请记住,让变量延迟加载,您需要使用let!或引用变量以将记录插入到测试数据库中。

# polyfill for Rails 4. Remove if you are using Rails 5.
let(:parsed_response) { response.body.to_json }

describe "GET #index" do  
  # or use fixtures / factories
  let!(:model) { Model.create!(foo: 'bar') }
  before :each do
    get :index, filtered: 'someValue'
  end
  expect(parsed_response.first["id"].to_i).to eq model.id
end