Rspec 和命名路由

29

我对rails还很陌生,正在尝试跟随railstutorial学习。除了我的测试无法通过命名路由(5.3.3)之外,一切都进行得很好。

我的routes.rb文件如下:

 SampleApp::Application.routes.draw do

 resources :users
 match '/signup',  to: 'users#new'

 match '/help',    to: 'static_pages#help'
 match '/about',   to: 'static_pages#about'
 match '/contact', to: 'pages#contact'

 root to: 'static_pages#home'

 #Commented stuff

我的第一次测试(spec/controllers/static_pages_controller_spec.rb):

describe "Static pages" do

subject { page }

shared_examples_for "all static pages" do
  it { should have_selector('h1',    text: heading) }
  it { should have_selector('title', text: full_title(page_title)) }
end

describe "Home page" do
  before { visit root_path }
  let(:heading)    { 'Sample App' }
  let(:page_title) { 'Home' }

  it_should_behave_like "all static pages"
end

#Other tests

spec_helper.rb的代码如下(省略了所有注释)

ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'

Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

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

我从rspec得到的错误都像这个:

 Static pages Home page it should behave like all static pages 
 Failure/Error: before { visit root_path }
 NameError:
   undefined local variable or method `root_path' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_1::Nested_1:0x00000004a12210>
 Shared Example Group: "all static pages" called from ./spec/controllers/static_pages_controller_spec.rb:17
 # ./spec/controllers/static_pages_controller_spec.rb:13:in `block (3 levels) in <top (required)>'
我已经尝试了使用。
 include Rails.application.routes.url_helpers

我在spec_helper文件中进行了更改,但它改变了我的错误信息

 Static pages Home page it should behave like all static pages 
 Failure/Error: Unable to find matching line from backtrace
 SystemStackError:
   stack level too deep
 # /usr/lib/ruby/1.9.1/forwardable.rb:185

我也尝试了不同的重命名路由的方法,但是它们都没有起作用。我回到了教程版本。

如果这能帮助找到问题所在,我使用的是Ubuntu 11.10,Rails 3.2.1和Ruby 1.9.2p290。希望你能帮忙,我花了很长时间在谷歌上搜索解决方案,但没有找到任何结果 ^^'

6个回答

118

如果您将以下内容放入rspec_helper.rb中,命名路由应该可以正常工作:

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

你是这样设置的吗?


这正是我所做的,除了 'config.' 部分。现在一切都完美运作!非常感谢! - FabPelletier
9
如果有人看到这里仍然困惑,值得注意的是,root_path(等等)仅在RSpec测试"describe"块内的"it"块的"do...end"块中起作用。因此,如果您创建了基于传递给函数的路径参数来处理"it"部分的函数,则无法将root_path(等等)作为参数传递给该函数。 - DreadPirateShawn
这也解决了我的Rails 4.2退化警告问题“DEPRECATION WARNING: named_routes.helpers已弃用,请使用route_defined?(route_name)来查看是否定义了命名路由”,所以现在我有干净的rspec日志,直到我等待https://github.com/rspec/rspec-rails/pull/1142发布。 - Jay Killeen
我认为你的意思是 rails_helper.rb - James Klein

3

我通过Google来到这里,但我的错误信息并不完全相符。

在我的情况下,Capybara命令visit是未知的...

错误:

NoMethodError:
       undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_1:0xa49a73c>

自从Capybara 2.0版本以来,您需要使用文件夹spec/features,因为在文件夹spec/requests中Capybara命令不再起作用。
这篇文章对我很有帮助:http://alindeman.github.com/2012/11/11/rspec-rails-and-capybara-2.0-what-you-need-to-know.html 希望这对您有所帮助。

3

我认为在 RSpec 控制器规范中无法访问命名路由。但你可以使用访问 '/' 的方式来代替 root_path。


谢谢,它很好用,使我的测试变成了绿色!然而,这个教程似乎使用了命名路由 railstutorial.org,我很好奇如何使用^^ - FabPelletier
请您点赞并接受答案,不用客气!:) - TheDelChop
点赞需要15个声望值,抱歉!我会等一段时间再接受它,以防有人真的知道如何使它“按照书上所说”工作 :) - FabPelletier

2
您应该使用:
rails generate rspec:install

替代

rspec --init

如果你事先知道了,你就不需要修改配置文件了。

但现在不要这样做,否则你的应用程序会崩溃,你将不得不浪费更多的时间来找出它为什么崩溃了。


8
但是你的评论并不是一个解决方案。;-) - Tass

2

我曾经遇到过同样的问题,和相同的教程。结果发现我只需要重新启动Spork服务,一切就正常了。

Tom L发布的解决方案对我有用,但当我删除那行代码并重新启动Spork时,问题也得到了解决。

希望这能帮助其他担心偏离教程代码的人!


1
非常感谢!@Tom L的代码对我没有用。所以这终究是Spork的问题!我花了整个下午寻找解决方案!非常感谢! - Ardee Aram

1

如果您将以下内容放入 rails_helper.rb 而不是 spec_helper.rb,则命名路由应该可以正常工作:

请查看我的 rails_helper.rb 代码


# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
# Prevent database truncation if the environment is production
if Rails.env.production?
  abort('The Rails environment is running in production mode!')
end
require 'rspec/rails'
require 'capybara/rails'
RSpec.configure do |config|
  config.include Rails.application.routes.url_helpers
  config.include Devise::Test::ControllerHelpers, type: :controller
  config.include Devise::Test::ControllerHelpers, type: :view
  config.include Warden::Test::Helpers
end

begin
  ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
  puts e.to_s.strip
  exit 1
end
RSpec.configure do |config|
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  config.use_transactional_fixtures = true

  config.infer_spec_type_from_file_location!

  # Filter lines from Rails gems in backtraces.
  config.filter_rails_from_backtrace!
end


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接