使用 RSPEC 测试依赖于环境的路由
Testing environment dependent routing with RSPEC
我有一些应该只存在于开发环境中的路线,但我无法获得这项工作的规范。知道我做错了什么吗?我最初在控制器规范中尝试过这个,但后来意识到我需要 :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)>'
路由在应用程序启动时加载一次,Rails.env
将是 'test'。
通常最好让您的开发环境尽可能接近生产环境,包括路由。
如果你想在开发环境中使用一些快捷方式,可以选择:
- 您可以使用常规
/ims/users/new
和 create
操作以及仅在开发中有效的参数。例如 /ims/users/new?development=true
也会呈现额外的隐藏字段以将状态传递给 create
- 对路由使用动态约束(这样路由仍会在 production/test 中列出,但无法访问)
- 保持路由始终存在,并在控制器中针对错误的环境引发错误
- 将整个 development_account-feature 提取到引擎中,单独测试并仅在开发中安装它(最难的方法,并非总是可行)
我会选择第一个选项,它既简单,封装得相对较好,而且很可能您的 *_development_account
无论如何都会模仿相应的操作
可以使用 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
我有一些应该只存在于开发环境中的路线,但我无法获得这项工作的规范。知道我做错了什么吗?我最初在控制器规范中尝试过这个,但后来意识到我需要 :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)>'
路由在应用程序启动时加载一次,Rails.env
将是 'test'。
通常最好让您的开发环境尽可能接近生产环境,包括路由。
如果你想在开发环境中使用一些快捷方式,可以选择:
- 您可以使用常规
/ims/users/new
和create
操作以及仅在开发中有效的参数。例如/ims/users/new?development=true
也会呈现额外的隐藏字段以将状态传递给create
- 对路由使用动态约束(这样路由仍会在 production/test 中列出,但无法访问)
- 保持路由始终存在,并在控制器中针对错误的环境引发错误
- 将整个 development_account-feature 提取到引擎中,单独测试并仅在开发中安装它(最难的方法,并非总是可行)
我会选择第一个选项,它既简单,封装得相对较好,而且很可能您的 *_development_account
无论如何都会模仿相应的操作
可以使用 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