8

我已经以正常方式创建了一个 Rails 引擎,安装了 RSpec,并为模型生成了一个脚手架,但我无法让任何路由规范通过。

这是一个例子:

describe Licensing::LicensesController do
  it 'routes to #index' do
    get('/licensing/licenses').should route_to('licensing/licenses#index')
  end
end

我在这样的虚拟应用程序中运行示例:

$ cd spec/dummy
$ rake spec
/Users/brandan/.rvm/rubies/ruby-1.9.3-p194/bin/ruby -S rspec ../routing/licensing/licenses_routing_spec.rb
F

Failures:

  1) Licensing::LicensesController routes to #index
     Failure/Error: get('/licensing/licenses').should route_to('licensing/licenses#index')
       No route matches "/licensing/licenses"
     # /Users/brandan/repos/licensing/spec/routing/licensing/licenses_routing_spec.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.04345 seconds
1 example, 1 failure

引擎已正确安装在虚拟应用程序中:

# spec/dummy/config/routes.rb
Rails.application.routes.draw do
  mount Licensing::Engine => "/licensing"
end

我可以进入虚拟应用程序并启动控制台并获得该路线就好了:

1.9.3p194 :001 > app.get('/licensing/licenses')
  Licensing::License Load (0.3ms)  SELECT "licensing_licenses".* FROM "licensing_licenses" 
200
1.9.3p194 :002 > app.response.body
"<!DOCTYPE html>..."

虚拟应用程序和 RSpec 之间存在一些差异,我无法弄清楚它是什么。我发现了几篇声称可以解决这个问题的文章,但没有一篇有帮助,其中一些是特定于 Rails 3.1 的:

有人在 Rails 3.2/RSpec 2.10 中解决了这个问题吗?

4

2 回答 2

10

更新 (2013-10-31)

RSpec 2.14 现在完全支持引擎路由

module MyEngine
  describe ExampleController do
    routes { MyEngine::Engine.routes }
  end
end

将其添加到所有路由规范中:

# spec/spec_helper.rb
config.include Module.new {
  def self.included(base)
    base.routes { Reportr::Engine.routes }
  end 
}, type: :routing

到目前为止,我能找到的最佳解决方案是明确设置将在测试期间使用的路由集:

RSpec.configure do |config|
  config.before(:each, type: :controller) { @routes = Licensing::Engine.routes }
  config.before(:each, type: :routing)    { @routes = Licensing::Engine.routes }
end

然后我不得不重写我的路由示例以省略命名空间:

it 'routes to #index' do
  get('/licenses').should route_to('licensing/licenses#index')
end

这看起来有点像黑客,但它确实有道理。我没有测试 Rails 是否能够在特定路径上安装引擎。我只是在测试我的引擎是否正确设置了自己的路线。不过,我宁愿不必覆盖实例变量来实现它。

以下是关于这个主题的另外几个很好的主题:

于 2012-08-11T15:03:39.190 回答
7

我认为您需要明确告知 RSpec 您正在使用命名空间 Rails 路由。例如,

# :use_route => ENGINE_NAMESPACE
:use_route => 'licensing'

此外,为什么不像这样简化 RSpec 控制器测试的编写,

describe Licensing::LicensesController do
  it 'GET index' do
    get :index, use_route: 'licensing'
  end
end

这是我做的 RSpec 控制器的链接, https://github.com/westonplatter/questionnaire_engine/tree/engine/spec/controllers

于 2012-08-11T03:10:57.627 回答