簡體   English   中英

如何在Rails 3.1可安裝引擎中測試路由

[英]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

資料來源: https//github.com/rspec/rspec-rails/pull/668

嘗試使用以下內容添加前塊:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM