【问题标题】:Gem tests can't find route using url_forGem 测试无法使用 url_for 找到路线
【发布时间】:2012-11-20 15:20:58
【问题描述】:

我认为运行我的 gem 测试的虚拟应用程序设置不正确,因为当我在 gem 的帮助程序中的 Gadget 实例(来自虚拟应用程序的存根模型)上调用 url_for 时,我得到

undefined method `gadgets_path' for #<#<Class:0x007fe274bc1228>:0x007fe273d45eb0>

背景:我创建了一个 gem 并进行了一些重大更改。 (Here's the fork.) 现在我正在尝试使 rspec 测试正常工作,以便我可以验证我的更新。

测试的设置类似于 Rails 引擎,在 spec 目录中有一个虚拟应用程序。该应用程序有一个模型 (Gadget),具有适当的控制器和在 spec/dummy/environment/routes.rb 文件中声明的资源:

Dummy::Application.routes.draw do
  resources :gadgets
end

spec/spec_helper.rb 文件如下所示:

ENV["RAILS_ENV"] ||= "test"

require File.expand_path("../dummy/config/environment", __FILE__)
require 'rspec/rails'

require 'rspec/autorun'

RSpec.configure do |config|
  config.mock_framework = :rspec
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = true
  config.infer_base_class_for_anonymous_controllers = false
  config.order = "random"

  config.include Rails.application.routes.url_helpers
end

(实际上,您可以在 the project's github repo 中看到完整的测试设置。我实际上是在一周左右之前为此打开了 an issue,但直到现在我才开始尝试解决它。​​)

未挂起的一个测试会创建一个 Gadget 实例,然后以它作为参数调用帮助程序。当助手尝试url_for(@gadget)时,会触发上述错误。

这里有什么问题?

ETA 12 月 04 日:更新为当前的 spec_helper.rb

【问题讨论】:

    标签: ruby-on-rails-3 routes gem rspec2 rspec-rails


    【解决方案1】:

    更新

    把它放在你的 spec_helper.rb 中——至少这对我有用(我克隆了你的 repo)

    ActionView::TestCase::TestController.instance_eval do
      helper Rails.application.routes.url_helpers#, (append other helpers you need)
    end
    ActionView::TestCase::TestController.class_eval do
      def _routes
        Rails.application.routes
      end
    end
    

    真正的问题是TestControllerActionController::Base 的子类之前 ActionController::Base 是使用路由辅助方法扩展的。
    所以你需要把它注入TestController。此外,AbstractController::UrlFor 需要实现 _routes


    为了使用路由助手,你应该插入

    Rspec.configure do |config|
      config.include Rails.application.routes.url_helpers
      ...
    end
    

    在您的 spec_helper.rb 中,这使得所有 something_path 方法都可用。 解决实际问题的另一种方法是像这样删除助手:

    helper.stub!(:url_for).and_return("/path")
    

    【讨论】:

    • 这看起来很有希望,当我进入虚拟应用程序并使用 Rails 控制台时,我可以戳那个对象并取回路径。但是,它不允许运行测试。我已经根据您的建议更新了上面的spec_helper.rb 代码。 (它也在 Github 上更新。)
    • 你对“真正的问题”是绝对正确的,而这本身就解决了问题。
    • 谢谢!这修复了引发此错误的规范:Failure/Error: helper.url_for(subdomain: 'app', controller: 'dashboard', action: 'index').should eq 'http://app.example.com/' RuntimeError: In order to use #url_for, you must include routing helpers explicitly. For instance, include Rails.application.routes.url_helpers
    【解决方案2】:

    虽然需要吸收相当多的源代码,但在我看来,您调用的是editable_field,而后者又调用了url_for。但是url_for 只能在控制器的上下文中工作,而您只是在规范的中间调用它。

    因此,也许将这个方法存根或进行集成测试是一个合适的解决方法。

    【讨论】:

    • editable_field 是一个辅助方法。 url_for 实际上在助手中工作得很好;它在测试环境中不起作用。存根 editable_field 不是一个合适的解决方法,因为它是我正在尝试测试的方法。
    • 如果你拉起 rails 控制台并执行editable_field 会起作用吗?我不认为它会,因为它需要在请求的上下文中,它为url_for 设置工作环境。所以我建议存根url_for 而不是editable_field。跨度>
    • 你说得对,它在控制台中不起作用。这是对 url_for 存根的三票,现在,这很有意义。
    • 另外,感谢您指出请求上下文以及它如何为url_for 设置环境。我没有意识到这一点,尽管现在我知道这当然是完全合理的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    相关资源
    最近更新 更多