【问题标题】:RSpec controller spec: How to test rendered JSON?RSpec 控制器规范:如何测试呈现的 JSON?
【发布时间】:2018-12-27 18:10:48
【问题描述】:

我正在尝试测试 Rails API 的简单控制器操作

这是有问题的控制器:

class Api::TransactionsController < ApplicationController
  def index
    transactions = Transaction.all
    json = TransactionSerializer.render(transactions)
    render json: json
  end
end

这是我目前的规格

require 'rails_helper'

RSpec.describe Api::TransactionsController do
  describe '.index' do
    context "when there's no transactions in the database" do
      let(:serialized_data) { [].to_json }

      before { allow(TransactionSerializer).to receive(:render).with([]).and_return(serialized_data) }
      after { get :index }

      specify { expect(TransactionSerializer).to receive(:render).with([]) }
      specify { expect(response).to have_http_status(200) }
    end
  end
end

我想测试响应。类似于这个 Stack Overflow 问题How to check for a JSON response using RSpec?:

specify { expect(response.body).to eq([].to_json) }

我的问题是response.body 是一个空字符串。这是为什么 ?

【问题讨论】:

  • 您对response.body 的期望是什么?此外,更好的做法是拥有expect(response).to have_http_status(:success)
  • 因为你在test环境下的数据库是空的。
  • 是的,数据库是空的,所以响应应该是一个空数组。此外,正如您在规范中看到的那样,我将序列化程序存根以返回一个空数组。
  • 我认为你需要在before块中调用get :index,否则没有响应体。
  • 是的,它有效并且有意义。谢谢

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


【解决方案1】:

不确定您使用的是哪种序列化程序。但是,render 不是ActiveModel::Serializer 上的方法。试试这个:

module Api
  class TransactionsController < ApplicationController
    def index
      transactions = Transaction.all
      render json: transactions
    end
  end
end

如果您的TransactionSerializerActiveModel::Serializer,按照惯例,Rails 将使用它来序列化ActiveRecord::Relation 中的每个事务记录。

然后,像这样测试它:

require 'rails_helper'

describe Api::TransactionsController do
  describe '#index' do
    context "when there's no transactions in the database" do
      let(:transactions) { Transaction.none }

      before do
        allow(Transaction).to receive(:all).and_return(transactions)

        get :index
      end

      specify { expect(response).to have_http_status(200) }
      specify { expect(JSON.parse(response.body)).to eq([]) }
    end
  end
end

这里的部分问题可能是直到 after 测试运行时您才真正调用 get :index。您需要在测试运行之前调用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-22
    • 2013-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多