2

我开始使用 Rspec,但是当我运行时bundle exec rspec出现错误

 /spec/requests/pages_spec.rb:20:in `block (2 levels) in <top (required)>': undefined local
 variable or method `root_path' for #<Class:0x00000102e46850> (NameError)

我没有运行 Spork 或 Guard,因此以下问题不适用

未定义的局部变量或方法“root_path”(Rspec Spork Guard)

我已经config.include Rails.application.routes.url_helpers在我的spec_helper.rb文件中添加了,但这没有帮助。 未定义的局部变量或方法 `root_path' Hartl's Tutorial Chapter 5.3.2

这里是pages_spec.rb

require 'spec_helper'                                                                                                                                                       

describe "Pages" do                                                                                                                                                         
  describe "navigation" do                                                                                                                                                  

    def self.it_should_be_on(path_name, value=nil)                                                                                                                          
      before { visit path_name }                                                                                                                                            

      it "should be on #{path_name}" do                                                                                                                                     
        page.should have_link('Home')                                                                                                                                       
        page.should have_link('Inventory')                                                                                                                                  
        page.should have_link('FAQ')                                                                                                                                        
        page.should have_link('About Us')                                                                                                                                   
        page.should have_link('Location')                                                                                                                                   
        page.should have_link('Contact Us')                                                                                                                                 
        # page.should have_link('Login')                                                                                                                                    
      end                                                                                                                                                                   
    end                                                                                                                                                                     

    it_should_be_on root_path                                                                                                                                               
    it_should_be_on faq_path                                                                                                                                                
    it_should_be_on about_path                                                                                                                                              
    it_should_be_on location_path                                                                                                                                           
    it_should_be_on contact_path                                                                                                                                            
    # it_should_be_on login_path                                                                                                                                            
  end                                                                                                                                                                       
end       

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'                                                                                                                                                     
# 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 }                                                                                                         

# Checks for pending migrations before tests are run.                                                                                                                       
# If you are not using ActiveRecord, you can remove this line.                                                                                                              
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)                                                                                                 

RSpec.configure do |config|                                                                                                                                                 
  # ## Mock Framework                                                                                                                                                       
  #                                                                                                                                                                         
  # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:                                                                                             
  #                                                                                                                                                                         
  # config.mock_with :mocha                                                                                                                                                 
  # config.mock_with :flexmock                                                                                                                                              
  # config.mock_with :rr                                                                                                                                                    

  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures                                                                                              
  config.fixture_path = "#{::Rails.root}/spec/fixtures"                                                                                                                     

  # If you're not using ActiveRecord, or you'd prefer not to run each of your                                                                                               
  # examples within a transaction, remove the following line or assign false                                                                                                
  # instead of true.                                                                                                                                                        
  config.use_transactional_fixtures = true                                                                                                                                  

  # If true, the base class of anonymous controllers will be inferred                                                                                                       
  # automatically. This will be the default behavior in future versions of                                                                                                  
  # rspec-rails.                                                                                                                                                            
  config.infer_base_class_for_anonymous_controllers = false                                                                                                                 

  # Run specs in random order to surface order dependencies. If you find an                                                                                                 
  # order dependency and want to debug it, you can fix the order by providing                                                                                               
  # the seed, which is printed after each run.                                                                                                                              
  #     --seed 1234                                                                                                                                                         
  config.order = "random"                                                                                                                                                   
  config.include Capybara::DSL                                                                                                                                              
  config.include Rails.application.routes.url_helpers                                                                                                                       
end                                              

更新 在阅读了有关 shared_examples 之后,我成功地尝试了这一点。有没有更好的方法来编写这个测试?我最终将页面分离成单独的页面,如主页等。

require 'spec_helper'                                                               

describe "Pages" do                                                                 

  subject { page }                                                                  

  shared_examples "navigation" do |path_name|                                       
    before { visit send( path_name) }                                               

    describe "navigation links should be on #{path_name}" do                        

      it { should have_link('Home') }                                               
      it { should have_link('Inventory') }                                          
      it { should have_link('FAQ') }                                                
      it { should have_link('About Us') }                                           
      it { should have_link('Location') }                                           
      it { should have_link('Contact Us') }                                         
      # it { should have_link('Login') }                                            
    end                                                                             
  end                                                                               

  describe "Home Page" do                                                           
    include_examples "navigation", :root_path                                       
  end                                                                               
end            
4

2 回答 2

5

describeRSpec块的顶层没有任何 Rails 助手可用。它们仅在较低级别的块中可用(例如letbeforeit等)。

如果您想在示例之间共享诸如此类的代码,您可以使用 shared_context 或 shared_example,如 RSpec 文档中所述,或者在describe级别切换到使用符号作为参数并将它们的解释推迟为方法,直到您在较低级别的块中,如@IharDrozdov 的答案所示。

于 2014-01-18T23:14:51.553 回答
1

要保存您的结构 - 您可以像这样更改代码:

require 'spec_helper'                                                                                                                                                       

describe "Pages" do                                                                                                                                                         
  describe "navigation" do                                                                                                                                                  

    shared_examples_for 'main page' do |path_name|                                                                                                                         
      before { visit send(path_name) }                                                                                                                                            

      it "should be on #{path_name}" do                                                                                                                                     
        page.should have_link('Home')                                                                                                                                       
        page.should have_link('Inventory')                                                                                                                                  
        page.should have_link('FAQ')                                                                                                                                        
        page.should have_link('About Us')                                                                                                                                   
        page.should have_link('Location')                                                                                                                                   
        page.should have_link('Contact Us')                                                                                                                                 
        # page.should have_link('Login')                                                                                                                                    
      end                                                                                                                                                                   
    end                                                                                                                                                                     

    it_should_behave_like 'main_page', :root_path                                                                                                                                               
    it_should_behave_like 'main_page', :faq_path                                                                                                                                                
    it_should_behave_like 'main_page', :about_path                                                                                                                                              
    it_should_behave_like 'main_page', :location_path                                                                                                                                           
    it_should_behave_like 'main_page', :contact_path                                                                                                                                            
    # it_should_behave_like 'main_page', :login_path                                                                                                                                            
  end                                                                                                                                                                       
end    

因为“路径未在规范中的类级别定义”(c)您不能在规范类中调用路径方法。它应该在it块中。而且你的结构并不完美。如果您想避免重复,最好将代码放在模块中然后包含它。

于 2014-01-18T23:16:44.780 回答