【问题标题】:Rails JSON API tests don't return json when exception is thrown抛出异常时,Rails JSON API 测试不返回 json
【发布时间】:2014-12-16 22:39:17
【问题描述】:

我正在编写一个测试来使用 Rspec 检查对 Rails API 的无效 DELETE 请求。

这就是我所拥有的:

context 'invalid id number' do
  it 'returns success: false' do
      xhr :delete, :destroy, id: 999999999999999999
      expect(JSON.parse(response.body)['success']).to be_false
  end
end

Postgres 抛出某种整数溢出异常(应该如此),但在我的规范中,我无法查看 JSON 对象,因为它从未形成。我怎样才能让它返回 { success : false } 而不是空白字符串?尽管出现异常,如何强制 JSON 对象返回?

当我使用 pry 查看 json 对象时,我收到此错误:JSON::ParserError: A JSON text must at least contain two octets! 因为 response.body 的计算结果为空字符串 ""

哇,差点忘了包含控制器代码。

def destroy
  if (site == ::MyModel.find(params[:id]))
    site.destroy
    render :json => {success: true}
  else
    render :json => {success: false} 
end

【问题讨论】:

    标签: ruby-on-rails json postgresql rspec


    【解决方案1】:

    这里有两个问题:

    1. 根据您的数据库,“999999999999999999”的 id 可能在整数类型之外。我建议将其降低到有符号整数限制以下,例如 9999。

    2. 您正在尝试查找不存在的记录并引发 record_not_found 异常。我建议将您的销毁方法更改为:


    def destroy
      site = ::MyModel.find_by(id:params[:id])
      if (site.present?)
        render :json => {success: false} 
      else
        site.first.destroy
        render :json => {success: true}
      end
    end
    

    编辑

    @rafb3 是正确的find_bypresent? 是更好的选择。

    【讨论】:

    • 您可以使用find_by(id: ...) 保存查询,然后检查site.present?。这样可以避免运行empty? 的查询
    【解决方案2】:

    听上去你需要某种救援声明来处理异常:

    rescue ArithmeticException => ex
      # We need to complete the contract and return json here
      @response = { success: false }
    end 
    

    如果您想了解有关合同的更多信息,请查看此link

    记住在失败响应中远离返回对象,就像在这种情况下你发回类似site的东西,site不存在或者数据库连接不存在你的异常响应代码可能有它自己的异常!

    也尽量远离rescue Exception => e这里的解释:Why is it a bad style to `rescue Exception => e` in Ruby?

    TLDR:您的请求总是需要一个 json 响应,因此在所有地方,即使失败,它也应该返回一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-16
      • 1970-01-01
      • 1970-01-01
      • 2019-03-09
      • 2015-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多