2014-01-18 91 views
2

我开始使用Rspec的,但是当我运行bundle exec rspec我得到一个错误Rspec的未定义的局部变量或方法root_path

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

我没有叉勺或保护运行,所以下面的问题不应适用

undefined local variable or method `root_path' (Rspec Spork Guard)

我在spec_helper.rb文件添加config.include Rails.application.routes.url_helpers,但这并没有帮助。 undefined local variable or method `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    
+0

路径没有在规范中的类级别定义 – apneadiving

+0

你是什么意思?路径未在导航描述块中定义? – Patrick

回答

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区块中。 而你的结构并不完美。如果你想避免重复,最好把代码放在模块中,然后包含它。

+0

我并不打算保持结构,但我想避免重复。你建议将代码放入模块中,那么更好的结构会是什么? – Patrick

+0

已编辑。在这种情况下,积木不是一个好主意。 shared_examples_for是更好的解决方案,彼得Alfvin如何建议=)。 –

+0

感谢您的编辑,我更新了这个问题,通过阅读您的两个人的答案来展示我的工作。类似的,但改变了一下结构。你怎么看? – Patrick

4

Rails的助手都不是可用的RSpec的describe块的顶级单个页面。它们仅在较低级别的块内可用(例如,let,before,it等)。

如果你想共享代码,比如这个跨越的例子,你可以使用一个shared_context或shared_example,作为RSpec的文档中描述的,或改用符号作为参数,而在describe水平和推迟他们的解释为方法,直到您位于较低级别块内,如the answer from @IharDrozdov中所示。

+0

这是最好的解释。 –

相关问题