首页 > 解决方案 > Rspec GET 到不同的端点一秒钟 - ActionController::UrlGenerationError

问题描述

在我的 Grape/Rails 应用程序中,我实现了维护模式,ApplicationController因此当此模式处于活动状态时,它将重定向到maintenance_mode_path应用程序中的任何位置。如何强制 rspec 暂时处于不同的端点,例如。api/v1/new_endpoint而整个测试发生在MaintenanceModeController?

maintenance_mode_controller_spec

context 'when maintenance mode is active' do

  context 'when current page is not maintenance page' do
    let(:call_endpoint) { get('/api/v1/new_endpoint') }

    it 'redirect to the maintenance page' do
      call_endpoint
      expect(response).to have_http_status(:redirect)
    end
  end
end

但是上面的代码我有一个错误

失败/错误:let(:call_endpoint) { get('/api/v1/bank_partners') }

ActionController::UrlGenerationError: 没有路由匹配 {:action=>"/api/v1/new_endpoint", :controller=>"maintenance_mode"}

标签: ruby-on-railsrspecgrape

解决方案


您根本无法使用控制器规范对此进行真正的测试。控制器规范创建一个带有模拟请求的控制器实例,然后您可以在其上运行测试。例如,当您get :show在控制器测试中调用时,您实际上是在调用#show模拟控制器上的方法。由于它实际上并没有创建 HTTP 请求,因此它无法与系统中的其他控制器进行实际交互。

请改用请求规范

# /spec/requests/maintainence_mode_spec.rb
require "rails_helper"

RSpec.describe "Maintenance mode", type: :request do
  context 'when maintenance mode is active' do
    context 'when current page is not maintenance page' do
      let(:call_endpoint) { get('/api/v1/new_endpoint') }
      it 'redirects to the maintenance page' do
        call_endpoint
        expect(response).to redirect_to('/somewhere')
      end
    end
  end
end

请求规范提供了控制器规范的高级替代方案。事实上,从 RSpec 3.5 开始,Rails 和 RSpec 团队都不鼓励直接测试控制器,而是支持像请求规范这样的功能测试。


推荐阅读