2013-07-10 105 views
1

在Rails 3.2.13應用程序中,我正在編寫一個名爲Business的模型。由於這種模式越來越胖,我決定把它一分爲二,提取與可用性到一個名爲Availability一個Rails關心的所有代碼,保存在models/concerns/businessNameError:嘗試執行rails測試時未初始化的常量

class Business 
    module Availability 
    extend ActiveSupport::Concern 

    AVAILABILITY_OPEN  = 1 
    AVAILABILITY_CLOSED  = -1 
    AVAILABILITY_COMPLETE = -2 

... 

由於涉及默認情況下不Rails中啓用,我已經把下面的行config/application.rb,以自動加載它們:

config.autoload_paths += %W(#{config.root}/app/models/concerns) 

的問題是,拆分後,我所有的測試都停止了工作,返回NameError: uninitialized constant Availability錯誤。我想我需要在我的測試中以某種方式要求這個問題,但是我還沒有設法做到這一點,而且我也不明白爲什麼這個問題即使在沒有使用它的測試中也是需要的。

以下是運行測試後的堆棧跟蹤返回:

NameError: uninitialized constant Availability 
    (erb):9:in `<main>' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/erb.rb:849:in `eval' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/erb.rb:849:in `result' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures/file.rb:51:in `render' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures/file.rb:43:in `rows' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures/file.rb:29:in `each' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:670:in `block (2 levels) in read_fixture_files' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures/file.rb:20:in `open' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:669:in `block in read_fixture_files' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:668:in `each' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:668:in `read_fixture_files' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:548:in `initialize' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:482:in `new' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:482:in `block (2 levels) in create_fixtures' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:479:in `map' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:479:in `block in create_fixtures' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:232:in `disable_referential_integrity' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:476:in `create_fixtures' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:895:in `load_fixtures' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:849:in `setup_fixtures' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:407:in `_run__871072887135343583__setup__3260066542044458782__callbacks' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:405:in `__run_callback' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:385:in `_run_setup_callbacks' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:81:in `run_callbacks' 
    /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/testing/setup_and_teardown.rb:35:in `run' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:919:in `block in _run_suite' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:912:in `map' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:912:in `_run_suite' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:657:in `block in _run_suites' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:655:in `each' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:655:in `_run_suites' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:867:in `_run_anything' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1060:in `run_tests' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1047:in `block in _run' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1046:in `each' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1046:in `_run' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1035:in `run' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:21:in `run' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:774:in `run' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:366:in `block (2 levels) in autorun' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:27:in `run_once' 
    /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:365:in `block in autorun' 

UPDATE

這是類Business的摘錄,其中包括Availability關注:

class Business < ActiveRecord::Base 
    include Availability 
    include EmailVirtualAttribute 
    include TelephoneVirtualAttribute 

    belongs_to :place 
    has_many :businesses_users 
    has_many :users,  :through => :businesses_users, :uniq => true 
    has_many :customers, :inverse_of => :business, :dependent => :destroy 
    has_many :emails,  :as => :contactable, :class_name => 'Email' 
    has_many :telephones, :as => :contactable, :class_name => 'Telephone' 

    ... 

開發/測試配置是標準配置,沒有變化hav Ë已經取得

test.rb

Rendezvous::Application.configure do 
    # Settings specified here will take precedence over those in config/application.rb 

    # The test environment is used exclusively to run your application's 
    # test suite. You never need to work with it otherwise. Remember that 
    # your test database is "scratch space" for the test suite and is wiped 
    # and recreated between test runs. Don't rely on the data there! 
    config.cache_classes = true 

    # Configure static asset server for tests with Cache-Control for performance 
    config.serve_static_assets = true 
    config.static_cache_control = "public, max-age=3600" 

    # Log error messages when you accidentally call methods on nil 
    config.whiny_nils = true 

    # Show full error reports and disable caching 
    config.consider_all_requests_local  = true 
    config.action_controller.perform_caching = false 

    # Raise exceptions instead of rendering exception templates 
    config.action_dispatch.show_exceptions = false 

    # Disable request forgery protection in test environment 
    config.action_controller.allow_forgery_protection = false 

    # Tell Action Mailer not to deliver emails to the real world. 
    # The :test delivery method accumulates sent emails in the 
    # ActionMailer::Base.deliveries array. 
    config.action_mailer.delivery_method = :test 

    # Raise exception on mass assignment protection for Active Record models 
    config.active_record.mass_assignment_sanitizer = :strict 

    # Print deprecation notices to the stderr 
    config.active_support.deprecation = :stderr 
end 

development.rb

Rendezvous::Application.configure do 
    # Settings specified here will take precedence over those in config/application.rb 

    # In the development environment your application's code is reloaded on 
    # every request. This slows down response time but is perfect for development 
    # since you don't have to restart the web server when you make code changes. 
    config.cache_classes = false 

    # Log error messages when you accidentally call methods on nil. 
    config.whiny_nils = true 

    # Show full error reports and disable caching 
    config.consider_all_requests_local  = true 
    config.action_controller.perform_caching = false 

    # Don't care if the mailer can't send 
    config.action_mailer.raise_delivery_errors = false 

    # Print deprecation notices to the Rails logger 
    config.active_support.deprecation = :log 

    # Only use best-standards-support built into browsers 
    config.action_dispatch.best_standards_support = :builtin 

    # Raise exception on mass assignment protection for Active Record models 
    config.active_record.mass_assignment_sanitizer = :strict 

    # Log the query plan for queries taking more than this (works 
    # with SQLite, MySQL, and PostgreSQL) 
    config.active_record.auto_explain_threshold_in_seconds = 0.5 

    # Do not compress assets 
    config.assets.compress = false 

    # Expands the lines which load the assets 
    config.assets.debug = true 
end 

更新2

看來,在執行測試時發生錯誤是由燈具造成的。如果我對fixtures :all加載test_helper.rb發表評論,並創建一個簡單的測試,只是聲明爲真,則此測試通過,但不會在加載固件時出現。

回答

3

最後,我發現我的所有測試失敗的原因是錯誤。我使用的是Availabiliy::,而不是使用Business::,引用Availability關注的常數。此外,我的測試與當前代碼不同步,這使得發現錯誤比應該更困難。用Business替換所有對Availability的引用解決了這個問題。這裏的教訓是:始終保持應用程序和測試代碼同步

感謝Lichtamberg的全力支持。

1

與特定型號試試吧..像用戶::確認

# -*- encoding : utf-8 -*- 
require 'active_support/concern' 

module Business::Availability 
    extend ActiveSupport::Concern 

這:

config.autoload_paths += Rails.root.join("app", "models", "concerns") 
+0

謝謝你的回答Lichtamberg,不幸的是它不斷返回相同的錯誤。有任何想法嗎? – Sergio

+0

請展示您的模型類 – Lichtamberg

+0

Lichtamberg,我已經更新了與'business'類的相關部分相關的問題。告訴我你是否需要更多東西。 – Sergio

0

我有種孤立的問題的根源,這是燈具。我在test_helper.rb中使用fixtures :all方法。將其更改爲僅運行customers.yml燈具,我就可以運行customer_test.rb而不會出錯。我還不知道什麼是違規裝置(我想businesses.yml和可能相關的,但我沒有檢查它),爲什麼造成這個問題。

相關問題