在 Rails 中使用 RSpec 和 Capybara 时未定义的方法“访问”
Posted
技术标签:
【中文标题】在 Rails 中使用 RSpec 和 Capybara 时未定义的方法“访问”【英文标题】:undefined method `visit' when using RSpec and Capybara in rails 【发布时间】:2013-02-15 09:56:31 【问题描述】:我无法让 capybara 使用 rspec。它给了我这个错误:
undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_1:0x16529f8 @example=nil>
我知道有很多关于此的帖子,但没有一个解决方案对我有用。它们中的大多数都涉及不在 /spec/features 中的规范 - 我的在其中。
首先是错误:
$bundle exec rspec spec
F
Failures:
1) security signs users in
Failure/Error: visit "/sessions/new"
NoMethodError:
undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_1:0x16529f8 @example=nil>
# ./spec/features/security_spec.rb:4:in `(root)'
Finished in 0.006 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/features/security_spec.rb:3 # security signs users in
我认为重要的是要注意,起初我使用的是 URL 帮助程序“new_sessions_path”,它一直给我一个错误undefined local variable or method 'new_sessions_path'
。我知道它是有效的,因为:
$ rake routes
logout_sessions GET /sessions/logout(.:format) sessions#logout
sessions POST /sessions(.:format) sessions#create
new_sessions GET /sessions/new(.:format) sessions#new
contracts POST /contracts(.:format) contracts#create
new_contracts GET /contracts/new(.:format) contracts#new
edit_contracts GET /contracts/edit(.:format) contracts#edit
GET /contracts(.:format) contracts#show
PUT /contracts(.:format) contracts#update
DELETE /contracts(.:format) contracts#destroy
root / contracts#index
我的宝石文件:
source 'https://rubygems.org'
gem 'rails', '3.2.11'
gem 'execjs'
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
gem 'uglifier', '>= 1.0.3'
end
gem 'jquery-rails'
gem 'activerecord-oracle_enhanced-adapter', '~> 1.4.1'
gem 'jruby-openssl'
gem 'therubyrhino'
gem 'kaminari'
gem 'nokogiri'
group :development do
gem 'warbler'
end
group :test do
gem 'rspec-rails'
gem 'capybara'
gem 'activerecord-jdbcsqlite3-adapter'
end
spec_helper.rb 在 my_app/spec 中:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
# Capybara integration
require 'capybara/rspec'
require 'capybara/rails'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each |f| require f
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_base_class_for_anonymous_controllers = false
config.order = "random"
# Include path helpers
config.include Rails.application.routes.url_helpers
end
my_app/spec/features/security_spec.rb:
describe "security", :type => :feature do
it "signs users in" do
visit "/sessions/new"
fill_in "username", :with => "user"
fill_in "password", :with => "pass"
click_button "Sign In"
page.should have_content('Login Successful')
end
end
我已经尝试在上面定义有:type => :feature
和没有:type => :feature
的测试。两种方式都没有区别。有什么想法我接下来应该尝试什么?
【问题讨论】:
Capybara: undefined method 'visit'的可能重复 @mlt 在第一段中我说:“我知道有很多关于此的帖子,但没有一个解决方案对我有用。其中大多数涉及不在 /spec/features 中的规范——我的在哪。”本段专门引用您链接到的问题。这个问题不仅有更高的投票,而且还附带一个解决方案 - 这与您链接问题上发布的最高投票答案(不是解决方案)不同。 【参考方案1】:尝试添加:
config.include Capybara::DSL
到您的配置块。
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each |f| require f
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_base_class_for_anonymous_controllers = false
config.order = "random"
# Include path helpers
config.include Rails.application.routes.url_helpers
config.include Capybara::DSL
end
【讨论】:
不,完全相同的问题,没有明显变化 这对我有用——非常感谢。尽管在我的其他项目中,我不需要这样做。什么情况下在一个项目中需要这样做,而在另一个项目中不需要?另外,这到底是做什么的? 也为我工作。非常感谢! 我的文件已经有要求'spec_helper',它被检查为这个问题的答案,但这对我有用。谢谢! 这对我不起作用:我收到一条错误消息,指出Capybara
是一个未定义的常量。我的 Cucumber 测试使用 Capybara 很好。【参考方案2】:
在我的功能顶部添加require 'rails_helper'
最终解决了我的问题:
require 'rails_helper'
describe "security", :type => :feature do
it "signs users in" do
visit new_sessions_path
fill_in "username", :with => "user"
fill_in "password", :with => "pass"
click_button "Sign In"
page.should have_content('Login Successful')
end
end
这对我来说似乎很奇怪,因为我看到的 rspec 和 capybara 的每个示例都没有这个要求,但是哦,好吧。问题解决了。
原始答案(旧版本的 rspec)
require 'spec_helper'
被旧版本的 RSpec 使用。更好的答案是require 'rails_helper'
。
【讨论】:
您应该将更新部分放在帖子的顶部。 接受自己的答案真的很糟糕,即使 Kocur4d 的答案更精确(并且忘记包含 rails_helper.rb 不会是更常见的问题)。您应该更改接受的答案,因为在包含它之前没有完成配置更改,您仍然会遇到相同的错误。【参考方案3】:尝试在 before
块中执行所有设置:
spec/features/security_spec.rb
describe "security" do
before do
visit "/sessions/new"
fill_in "username", :with => "user"
fill_in "password", :with => "pass"
click_button "Sign In"
end
it "signs users in" do
page.should have_content('Login Successful')
end
end
【讨论】:
这实际上是错误的常见原因。visit
函数仅在 it
块内可用。 Source
不正确——before
块中的代码在示例上下文中运行,因此visit
将在那里以及it
块中工作。
@user912563,最终,既然你解决了你自己的问题,我的回答真的变成了一种风格建议,而不是其他任何东西(在before
块中设置代码是我编写规范的方式,他们工作没有错误;-)),所以我认为接受你自己的答案是公平的。
感谢@zetetic 和@Paul-Firavanti - 我不知道before
仍然在it
上下文中。使用它将使我的其他需要登录的测试更加干净
这对我很有帮助,因为我是个菜鸟,而且没有包含测试"" do ... end.【参考方案4】:
由于 Capybara 2.0 必须使用文件夹规范/功能 Capybara 命令不再适用于文件夹规范/请求。
【讨论】:
正如我的问题所述,我的水豚测试已位于spec/features
下。但这对于可能遇到问题的其他人来说是一个有效的观点。
我发现创建目录mkdir spec/features
并创建符号链接ln -s spec/features spec/requests
很有帮助。这样,任何生成的测试都将放置在 features 目录中。
感谢@ThillaiNarayanan,这是我遵循较旧的设置指南的问题,但在较新的 Capybara 版本上【参考方案5】:
我也有这个问题,
在我的功能顶部添加 require 'rails_helper' 最终解决了我的问题:
require 'rails_helper'
RSpec.describe "Products", type: :request do
describe "GET /products" do
it "display tasks" do
Product.create!(:name => "samsung")
visit products_path
page.should have_content("samsung")
#expect(response).to have_http_status(200)
end
end
end
并在 rails_helper.rb 中添加 'config.include Capybara::DSL'
RSpec.configure do |config|
config.fixture_path = "#::Rails.root/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_spec_type_from_file_location!
config.include Capybara::DSL
end
【讨论】:
添加配置行对我有用。这很奇怪,因为我在我的一个规范文件中得到了错误,但在另一个规范文件中没有,并且都调用了相同的 capy 方法(并且都需要 rails_helper)以上是关于在 Rails 中使用 RSpec 和 Capybara 时未定义的方法“访问”的主要内容,如果未能解决你的问题,请参考以下文章
在 Rails 3.1 中使用 Capybara、Rspec 和 Selenium 进行测试时登录失败
如何将内存中的 MongoDB 与 Rails、Mongoid 和 Rspec 一起使用?
rails3, rspec2 ActiveRecord#changes 规格中的错误
Rails 和 RSpec:在不同的命名空间(模块)中测试具有相同名称的控制器