我正在尝试为可安装的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版本中解决了这个问题,所以我已经相应地更改了我接受的答案。
答案 0 :(得分:12)
自RSpec 2.14起,您可以使用以下内容:
describe "test controller routing" do
routes { Testy::Engine.routes }
# ...
end
答案 1 :(得分:11)
尝试使用以下内容添加前一个块:
before(:each) { @routes = Testy::Engine.routes }
这对我有用,因为路由规范使用该顶级实例变量来测试其路由。
答案 2 :(得分:11)
史蒂芬安德森的回答让我大部分都在那里,但需要相对于引擎而不是应用程序提出请求 - 可能是因为这种技术用引擎的路线取代了应用程序的路线,所以现在一切都是相对于发动机。这对我来说似乎有点脆弱,但我还没有看到另一种有效的方式。如果有人发布了更清洁的方式,我会很乐意接受这个答案。
在'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
答案 3 :(得分:4)
这对我有用:
# spec_helper.rb
RSpec.configure do |config|
config.include MyEngine::Engine.routes.url_helpers
end
答案 4 :(得分:1)
对我来说,这是迄今为止所有参与者的评论组合。
首先,我从这个简单的测试开始:
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 => '/' }
,事情开始变得很好。不知道为什么。根据{{3}},没有区别,但它对我有所影响。无论如何,谢谢@ 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")
中提琴,它过去了。谢谢@ steven-anderson。
下一部分很奇怪。为特定小部件添加另一个测试后,该小部件使用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。使这个奇怪的是,稍后在创建此注释时,我删除了该配置条目以尝试将错误恢复,我无法通过删除配置条目来重现错误。哦,我继续前进。希望这个冗长的帐户有助于某人。
答案 5 :(得分:1)
基于this回答,我选择了以下解决方案:
#spec/spec_helper.rb
RSpec.configure do |config|
# other code
config.before(:each) { @routes = MyEngine::Engine.routes }
end
附加好处是,您不需要在每个控制器规范中都有before(:each)
块。