如果我在功能规范中调用 url_for
,它会返回一个以 http://www.example.com/ 开头的绝对 URL . Capybara 会很乐意尝试加载该站点上的页面,但这与我的应用程序无关。以下是重现该问题的最少步骤:
从这个 Gemfile 开始:
source 'https://rubygems.org'
gem "sqlite3"
gem "jquery-rails"
gem "draper"
gem "rails", '4.1.0'
gem "therubyracer"
gem "uglifier"
gem "rspec-rails"
gem "capybara"
gem "poltergeist"
gem "launchy"
运行以下命令:
bundle
rails new myapp -O
cd myapp
rm Gemfile Gemfile.lock
rails generate controller Test test
rails generate rspec:install
mkdir spec/features
注释掉 spec/spec_helper.rb
中表示在不使用 ActiveRecord 时应将其删除的行,然后创建 spec/features/feature_spec.rb
以下内容:
require 'capybara/poltergeist'
Capybara.configure do |config|
config.javascript_driver = :poltergeist
end
require 'spec_helper'
describe "nothing", js: true do
specify do
visit(url_for(controller: :test, action: :test))
save_and_open_page
end
end
最后,运行 rake spec
,您将看到 example.com 页面在浏览器中弹出。我已将此行为验证回 Rails 3.2.17。
为什么会这样,有没有办法获取正在测试的应用程序的 URL 而不是 example.com?
编辑:我进一步研究发现的一些东西:
ActionDispatch::Routing::UrlFor.url_for从 RSpec 示例中调用。它有 only_path
默认为 false。
ActionView::RoutingUrlFor是您在 View 中获得的版本。它的 only_path
默认为 true,效果更好。
This commit通过将 www.example.com
作为默认主机添加到 rspec-rails gem 可能会导致问题。没有任何地方解释为什么这个主机是一个合适/有用的选择。
最佳答案
出现问题的原因如下:
- 您正在使用 Poltergeist,它使用 PhantomJS,完全能够打开任何 URL。
- 您正在使用 url_for 助手,它需要知道应该为其生成 url 的域。当在 Rails View 或 Controller 中使用时,Rails 会根据用于发出请求的内容提供域。当在 View 或 Controller 之外时,例如在 ActionMailer 或 Capybara 测试中,域是未知的。 capybara 将未知域默认为 example.com。
所以一切都在按照它应该的方式工作。现在,它恰好不是您希望它工作的方式。但是,如果您希望它按您希望的方式工作,您应该执行以下操作之一:
- 在 url_for 中使用
path_only
选项告诉它不要使用主机部分。 - 使用 url_for 中的
host
选项指定正确的主机。
关于ruby-on-rails - 在 Rails/Capybara/Poltergeist 规范中使用 url_for 将驱动程序发送到 example.com 而不是应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23163836/