在Rails 5中测试应用程序控制器救援状态代码的最佳方法是什么?

时间:2017-10-28 04:44:45

标签: ruby-on-rails ruby rspec

本周末我遇到了一个有趣的挑战。我想测试以下4个救援声明。你觉得最好的方法是什么?我一直在测试匿名控制器,获取等等,但我是空白的。这甚至可能吗?

Rspec的

# frozen_string_literal: true

require 'rails_helper'

RSpec.describe ApplicationController, type: :controller do
  it 'rescue record not found with 404' do

  end

  it 'rescue parameter missing with 400' do

  end

  it 'rescue routing error with 400' do

  end

  it 'rescue invalid authenticity token with 400' do

  end
end

应用程序控制器

# frozen_string_literal: true

class ApplicationController < ActionController::Base
  force_ssl if: :ssl_configured?

  rescue_from ActiveRecord::RecordNotFound, with: :render_404
  rescue_from ActionController::ParameterMissing, with: :render_400
  rescue_from ActionController::RoutingError, with: :render_404
  rescue_from ActionController::InvalidAuthenticityToken, with: :render_400

  include StatusCodes
  include JsonTester

  private

  def ssl_configured?
    AppUnsecure.settings[:ssl_configured]
  end
end

1 个答案:

答案 0 :(得分:1)

正如@max所说,你不能以这种方式测试路由错误,因为它在堆栈中比控制器更早被提升。

但是,对于其他测试用例,您可以非常轻松地完成此操作:

RSpec.describe ApplicationController do
  controller do
    def test_record_not_found
      raise ActiveRecord::RecordNotFound
    end

    def test_parameter_missing
      raise ActionController::ParameterMissing, :test
    end

    def test_invalid_auth_token
      raise ActionController::InvalidAuthenticityToken
    end
  end

  before :each do
    routes.draw do
      get "test_record_not_found" => "anonymous#test_record_not_found"
      get "test_parameter_missing" => "anonymous#test_parameter_missing"
      get "test_invalid_auth_token" => "anonymous#test_invalid_auth_token"
    end
  end

  it "rescues record not found with 404" do
    get :test_record_not_found
    expect(response).to have_http_status(404)
  end

  it "rescues parameter missing with 400" do
    get :test_parameter_missing
    expect(response).to have_http_status(400)
  end

  it "rescues invalid auth token with 400" do
    get :test_invalid_auth_token
    expect(response).to have_http_status(400)
  end
end