[英]How to test routes in a Rails 3.1 mountable engine
我正在嘗試為可安裝的rails 3.1引擎編寫一些路由規范。 我有工作模型和控制器規格,但我無法弄清楚如何指定路線。
對於示例引擎'testy',我嘗試的每種方法都以相同的錯誤結束:
ActionController::RoutingError: No route matches "/testy"
我已經嘗試了Rspec和Test :: Unit語法(spec / routing / index_routing_spec.rb):
describe "test controller routing" do
it "Routs the root to the test controller's index action" do
{ :get => '/testy/' }.should route_to(:controller => 'test', :action => 'index')
end
it "tries the same thing using Test::Unit syntax" do
assert_routing({:method => :get, :path => '/testy/', :use_route => :testy}, {:controller => 'test', :action => 'index'})
end
end
我已經正確布局了路由(config / routes.rb):
Testy::Engine.routes.draw do
root :to => 'test#index'
end
並將它們安裝在虛擬應用程序中(spec / dummy / config / routes.rb):
Rails.application.routes.draw do
mount Testy::Engine => "/testy"
end
並運行rails server
並請求http://localhost:3000/testy/
工作正常。
我錯過了任何明顯的東西,或者這只是沒有適當地融入框架中了嗎?
更新:正如@andrerobot指出的那樣,rspec人員已經在2.14版本中解決了這個問題,所以我相應地改變了我接受的答案。
從RSpec 2.14開始,您可以使用以下內容:
describe "test controller routing" do
routes { Testy::Engine.routes }
# ...
end
嘗試使用以下內容添加前塊:
before(:each) { @routes = Testy::Engine.routes }
這對我有用,因為路由規范使用頂級實例變量來測試他們的路由。
Steven Anderson的答案讓我大部分都在那里,但需要相對於引擎而不是應用程序提出請求 - 可能是因為這種技術用引擎的路線替換了應用程序的路線,所以現在一切都相對於發動機。 這對我來說似乎有點脆弱,但我還沒有看到另一種有效的方式。 如果有人發布了更清潔的方式,我會很樂意接受這個答案。
在'dummy'應用程序中,如果引擎安裝如下(spec / dummy / config / routes.rb):
Rails.application.routes.draw do
mount Testy::Engine => "/testy"
end
以下規范將使用rspec和test :: unit語法(spec / routing / index_route_spec.rb)正確測試引擎的根路由:
require 'spec_helper'
describe "test controller routing" do
before(:each) { @routes = Testy::Engine.routes }
it "Routes the root to the test controller's index action" do
{ :get => '/' }.should route_to(:controller => 'testy/test', :action => 'index')
end
it "tries the same thing using Test::Unit syntax" do
assert_routing({:method => :get, :path => '/'}, {:controller => 'testy/test', :action => 'index'})
end
end
這對我有用:
# spec_helper.rb
RSpec.configure do |config|
config.include MyEngine::Engine.routes.url_helpers
end
對我來說,這是迄今為止所有參與者的評論組合。
首先,我從這個簡單的測試開始:
it "routes / to the widgets controller" do
get('/').should route_to("mozoo/widget#index")
end
這導致:
Failures:
1) Mozoo::WidgetController GET widget index routes / to the widgets controller
Failure/Error: get('/').should route_to("mozoo/widget#index")
ActionController::RoutingError:
No route matches {:controller=>"mozoo/widget", :action=>"/"}
# ./spec/controllers/mozoo/widget_controller_spec.rb:9:in `block (3 levels) in <module:Mozoo>'
所以我從get('/')
切換到{ :get => '/' }
,事情開始變得很好。 不知道為什么。 根據lib / rspec / rails / matchers / routing_matchers.rb L102-105 ,沒有區別,但它對我有所影響。 無論如何,謝謝@ cameron-pope。
接下來,我添加了另一個非常簡單且非常相似的測試,如上所述:
it "routes root_path to the widgets controller" do
{ :get => root_path }.should route_to("mozoo/widget#index")
end
並得到這個錯誤:
Failures:
1) Mozoo::WidgetController GET widget index routes root_path to the widgets controller
Failure/Error: { :get => '/mozoo' }.should route_to("mozoo/widget#index")
No route matches "/mozoo"
# ./spec/controllers/mozoo/widget_controller_spec.rb:14:in `block (3 levels) in <module:Mozoo>'
所以我補充說:
before(:each) { @routes = Mozoo::Engine.routes }
並得到一個更好/不同的錯誤:
Failures:
1) Mozoo::WidgetController GET widget index routes root_path to the widgets controller
Failure/Error: { :get => root_path }.should route_to("mozoo/widget#index")
The recognized options <{"controller"=>"mozoo/widget", "action"=>"index", "section"=>"mozoo"}> did not match <{"controller"=>"mozoo/widget", "action"=>"index"}>, difference: <{"section"=>"mozoo"}>.
<{"controller"=>"mozoo/widget", "action"=>"index"}> expected but was
<{"controller"=>"mozoo/widget", "action"=>"index", "section"=>"mozoo"}>.
# ./spec/controllers/mozoo/widget_controller_spec.rb:14:in `block (3 levels) in <module:Mozoo>'
從那里,我改變了我的測試以包括該部分(我的引擎所在的命名空間):
{ :get => root_path }.should route_to(:controller => "mozoo/widget", :action => "index", :section => "mozoo")
而中提琴,它通過了。 謝謝@史蒂文安德森。
下一部分很奇怪。 為特定小部件添加另一個測試后,該小部件使用widget_path url helper作為命名路由:
it "will successfully serve the widget show page" do
visit widget_path(:foobar)
response.should be_success
end
測試迅速炸毀了我:
Failures:
1) GET bubble_summary_row widget will have the content section properly scoped
Failure/Error: visit widget_path(:bubble_summary_row)
NoMethodError:
undefined method `widget_path' for #<RSpec::Core::ExampleGroup::Nested_3:0x0000010748f618>
# ./spec/views/mozoo/widgets/show.html.haml_spec.rb:7:in `block (2 levels) in <module:Mozoo>'
所以我添加了以下spec_helper配置條目:
RSpec.configure do |config|
config.include Testy::Engine.routes.url_helpers
end
和BAM! 它過去了。 謝謝@sam-soffes。 使這個奇怪的是,稍后在創建此注釋時,我刪除了該配置條目以嘗試並返回錯誤,我無法僅通過刪除配置條目來重現錯誤。 哦,我繼續前進。 希望這個冗長的帳戶可以幫助某人。
根據這個答案,我選擇了以下解決方案:
#spec/spec_helper.rb
RSpec.configure do |config|
# other code
config.before(:each) { @routes = MyEngine::Engine.routes }
end
額外的好處是,您不需要在每個控制器規范中都有before(:each)
塊。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.