在rails中使用RSpec和Capybara时未定义的方法`visit'

lig*_*h05 88 ruby rspec ruby-on-rails capybara

我不能让capybara与rspec合作.它给了我这个错误:

undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_1:0x16529f8 @example=nil>
Run Code Online (Sandbox Code Playgroud)

我知道有很多关于此的帖子,但没有解决方案对我有用.他们中的大多数涉及的规格不在/ 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
Run Code Online (Sandbox Code Playgroud)

我认为重要的是要注意,起初我使用URL Helper'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
Run Code Online (Sandbox Code Playgroud)

我的Gemfile:

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
Run Code Online (Sandbox Code Playgroud)

my_app/spec中的spec_helper.rb:

# 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
Run Code Online (Sandbox Code Playgroud)

my_app应用/规格/功能/ 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
Run Code Online (Sandbox Code Playgroud)

无论有没有,我都试过定义上面的测试:type => :feature.无论如何都没有区别.我接下来应该尝试什么想法?

Koc*_*r4d 195

尝试添加:

  config.include Capybara::DSL
Run Code Online (Sandbox Code Playgroud)

到您的配置块.

# 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
Run Code Online (Sandbox Code Playgroud)

  • 这对我有用 - 非常感谢.在我的其他项目中,我不需要这样做.什么情况会在一个项目中使这个必要,而不是另一个项目?这究竟是做什么的? (7认同)

lig*_*h05 52

添加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
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎很奇怪,因为我见过的所有rspec和capybara的例子都没有这个要求,但是哦.问题解决了.

原始答案(旧版本的rspec)

require 'spec_helper'由旧版本的RSpec使用.更好的答案是require 'rails_helper'.

  • 您应该将更新部分放在帖子的顶部. (4认同)

Thi*_*nan 34

由于Capybara 2.0必须使用文件夹规范/功能Capybara命令不再适用于文件夹规范/请求.

  • 正如我的问题所述,我的水豚测试**已经位于`spec/features`下.但对于可能遇到问题的其他人来说,这是一个有效的观点. (2认同)

Pau*_*nti 5

尝试在before块中执行所有设置:

规格/功能/ 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
Run Code Online (Sandbox Code Playgroud)

  • 不正确 - "before"块中的代码在示例上下文中运行,因此`visit`将在那里以及`it`块中运行. (4认同)
  • 这实际上是错误的常见原因**.`visit`函数仅在`it`块中可用.[来源](http://stackoverflow.com/a/11911471/912563) (2认同)
  • @ user912563,最终,既然你解决了自己的问题,我的答案真的变成了一个风格建议而不是其他任何东西(在`之前'块中设置代码是我编写规范的方式,它们的工作没有错误;-)),所以我认为接受你自己的答案是公平的. (2认同)