【问题标题】:Testing environment dependent routing with RSPEC使用 RSPEC 测试环境相关路由
【发布时间】:2020-01-09 11:48:01
【问题描述】:

我有一些只应存在于开发环境中的路线,但我无法获得该工作的规范。任何想法我做错了什么?我最初在控制器规范中尝试过这个,但后来意识到我需要 :type => :routing 才能使用 be_routable 所以把它分开了。我已经调试并且 Rails.env 在每个上下文中都有我期望的值。我需要重新加载路线吗?已尝试执行此操作,但找不到 rspec 满意的语法...

来自 routes.rb 的片段:

    resources :users do
        collection do
          ...
          if Rails.env.development?
            get :new_development_account
            post :create_development_account
          end
        end
        ...

路由规范:

require 'spec_helper'

describe "routes for users controller", :type => :routing do

    context "production environment" do
      it "development routes do not exist" do
        allow(Rails).to receive(:env) { "production".inquiry }
        expect(:get => "/ims/users/new_development_account").not_to be_routable
        expect(:post => "/ims/users/create_development_account").not_to be_routable
      end
    end

    context "development environment" do
      it "development routes exist" do
        allow(Rails).to receive(:env) { "development".inquiry }
        expect(:get => "/ims/users/new_development_account").to be_routable
        expect(:post => "/ims/users/create_development_account").to be_routable
      end
    end
end

特别奇怪的是它两次测试都失败了:

Failures:

  1) routes for users controller production environment development routes do not exist
     Failure/Error: expect(:get => "/ims/users/new_development_account").not_to be_routable
       expected {:get=>"/ims/users/new_development_account"} not to be routable, but it routes to {:action=>"show", :controller=>"ims/users", :id=>"new_development_account"}
     # /var/code/bundle/ruby/2.2.0/gems/given_core-3.5.4/lib/given/rspec/monkey.rb:31:in `handle_matcher'
     # ./spec/routing/users_controller_spec.rb:9:in `block (3 levels) in <top (required)>'
     # ./spec/support/database_cleaner.rb:18:in `block (2 levels) in <top (required)>'

  2) routes for users controller development environment development routes exist
     Failure/Error: expect(:post => "/ims/users/create_development_account").to be_routable
       expected {:post=>"/ims/users/create_development_account"} to be routable
     # /var/code/bundle/ruby/2.2.0/gems/given_core-3.5.4/lib/given/rspec/monkey.rb:21:in `handle_matcher'
     # ./spec/routing/users_controller_spec.rb:18:in `block (3 levels) in <top (required)>'
     # ./spec/support/database_cleaner.rb:18:in `block (2 levels) in <top (required)>'

【问题讨论】:

    标签: ruby-on-rails rspec-rails


    【解决方案1】:

    路由在应用启动时加载一次,Rails.env 将是“测试”。

    通常最好让您的开发环境尽可能接近生产环境,包括路线。

    如果您想在开发环境中使用一些快捷方式,可以选择:

    1. 您可以使用常规的/ims/users/newcreate 操作和仅在开发中有效的参数。例如/ims/users/new?development=true,它还将渲染额外的隐藏字段以将状态传递给create
    2. 对路由使用动态约束(这样路由仍会在生产/测试中列出,但不可访问)
    3. 保持路由始终存在,并在控制器中针对错误环境引发错误
    4. 将整个 development_account-feature 提取到引擎中,单独测试并仅在开发中安装(最难的方法,并非总是可行)

    我会选择第一个选项,它既简单,封装也相对较好,而且很可能您的 *_development_account 无论如何都会模仿相应的操作

    【讨论】:

    • 是的,我们最后选择了选项 1,只是觉得奇怪的是路由配置允许您有条件地设置它,但它不可测试。
    【解决方案2】:

    可以使用Rails.application.reload_routes!重新加载路由。

    例子:

    it "does not have routes in production" do
      allow(Rails).to receive(:env) { "production".inquiry }
      Rails.application.reload_routes!
      expect(:get => "/ims/users/new_development_account").not_to be_routable
      expect(:post => "/ims/users/create_development_account").not_to be_routable
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-21
      • 2011-08-04
      • 1970-01-01
      • 2012-02-12
      • 1970-01-01
      • 2010-12-18
      • 2011-04-20
      • 1970-01-01
      相关资源
      最近更新 更多