【问题标题】:rspec not calling 'to_json' implicitly on 'render(json: @instance)'rspec 不在 \'render(json: @instance)\' 上隐式调用 \'to_json\'
【发布时间】:2023-01-12 04:48:27
【问题描述】:

我不确定这是一个直接的 rspec 错误,但是在测试控制器操作时,我们希望我们的响应是我们正在获取的实例的 json 对象。我们收到的是一个 json 对象

=> render(json: @instance)
"{\"type\":\"class_name\"}"

如果我在渲染时在我的实例上手动调用“.to_json”

=> render(json: @instance.to_json)
<full object json response>

我得到了我的整个对象的完整响应,这是预期的行为并且与开发和生产环境相匹配。

我看不出为什么在从 rspec 调用时不调用隐式 'to_json' 的原因,这在 rails 文档中有说明

任何帮助是极大的赞赏。 TIA

编辑

控制器动作

def show
  render(json: @book)
end

book_controller_spec.rb 'json' 是一个自定义的 JSONHelper,它只解析 response.body

RSpec.describe(Api::V1::BooksController, type: :controller) do
  before :each do
    create(:book)
  end

  context '#show' do
    it 'returns the book with the correct ID' do
      get :show, params: { id: 1 }
      puts response.body
      json_response = JSON.parse(response.body, symbolize_names: true)
      expect(json_response[:id]).to(eq(1))
    end
  end
end

回复

{"type":"book"}

【问题讨论】:

  • 你能发布相关代码吗(例如测试和它正在测试的控制器动作?)
  • 按要求编辑
  • 1) 你能告诉我们json的代码吗? 2) 检查response.body。 3)什么是实际测试失败?
  • 1) JSON.parse(response.body, symbolize_names: true) 2) "{\"type\":\"class_name\"}" 3) 我不担心测试失败,因为我们无法获得一个对象还没有测试。它应该返回一个带有 id、名称等的完整对象,但我们只得到问题 2 的响应
  • 出于这个问题的目的,我建议用 JSON 解析、清晰的测试和测试结果替换 json 函数,它对我们来说是不透明的。为了确定,我也会在控制器中使用p @book

标签: json ruby-on-rails rspec render rspec-rails


【解决方案1】:

我建议编辑您的测试以请求 JSON 响应。我搜索了更多有关该问题的信息;在 RSpec 上设置请求标头可能很棘手。您可以执行以下操作。

  it 'forces a JSON response' do
    get :show, params: { id: 1 }, format: :json
  end

【讨论】:

  • 我会按照说明尝试您的代码,但我相当确定这是在某个阶段尝试过的。我会回复结果?
  • 我试过你的答案 Christos 但不幸的是它对响应没有任何影响。另外,仅供参考,'headers' 不是可接受的参数。认为这可能与 rspec-rails 的版本有关,但不完全确定。我这样写你的代码是为了让标题被接受。我在请求中检查了这些,它们确实通过了,但响应没有改变 ``` headers = { ACCEPT: 'application/json', 'CONTENT-TYPE': 'application/json' } request.headers.merge!(标头)得到:显示,参数:{id:1}```
  • @bubbaspaarx 我更新了我的答案,这应该可以解决您的问题。我还对其进行了测试,我可以在日志中看到它调用控制器作为 JSON 操作。
  • 我现在也尝试过这段代码,但仍然遇到同样的问题。响应已经是 JSON 格式,所以这不是最初的问题,但它在返回对象之前仍然没有对对象执行 .to_json。此外,我们必须为 Rails 6 调整代码,使其变为 :show, params: { id: 1, format: :json }
【解决方案2】:
context '#show' do 
  it 'return book with id' do 
   book = Book.create(params)  #or create by factorybot book= create :book
   get :show, params: {id: 1},format: :json
   expect(JSON.parse(response.body)['id']).to eq(1)
  end
end

【讨论】:

  • 我没有添加书籍创作,因为那不是问题所在。这本书存在
猜你喜欢
  • 1970-01-01
  • 2022-12-01
  • 2013-02-21
  • 1970-01-01
  • 1970-01-01
  • 2017-01-13
  • 2010-10-11
  • 1970-01-01
  • 2019-10-30
相关资源
最近更新 更多