13

我不知道如何让 spork 不加载我所有的应用程序模型。由于我无法使用 spork 来提供帮助,因此测试对我的模型所做的更改大大减慢了速度。这是我调试 spork 正在加载的内容时得到的结果:

    - 孢子诊断 -
    -  概括  - 
    应用程序/模型/account.rb
    应用程序/模型/admin.rb
    应用程序/模型/affiliate.rb
    应用程序/模型/app.rb
    应用程序/模型/application_server.rb
    应用程序/模型/domain_record.rb
    应用程序/模型/domain_zone.rb
    应用程序/模型/事件.rb
    应用程序/模型/oid.rb
    应用程序/模型/user.rb
    配置/应用程序.rb
    配置/boot.rb
    配置/环境.rb
    配置/环境/test.rb
    配置/初始化程序/api_conversions.rb
    config/initializers/backtrace_silencers.rb
    配置/初始化程序/compass.rb
    配置/初始化程序/devise.rb
    配置/初始化程序/hoptoad.rb
    config/initializers/inflections.rb
    配置/初始化程序/mime_types.rb
    配置/初始化程序/rspec_generator.rb
    配置/初始化程序/secret_token.rb
    配置/初始化程序/session_store.rb
    配置/路由.rb
    lib/application_server_api.rb
    lib/oid_helper.rb
    库/soa_record.rb
    规范/spec_helper.rb



    -  细节  - 



    --- app/models/account.rb ---
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:239:in `block in require'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:227:in `load_dependency'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:239:in `require'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:346:in `require_or_load'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:300:in `depend_on'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:216:in `require_dependency'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/mongoid-2.0.0.rc.7/lib/rails/mongoid.rb:54:in `load_model'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/mongoid-2.0.0.rc.7/lib/rails/mongoid.rb:17:in `block (2 levels) in load_models'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/mongoid-2.0.0.rc.7/lib/rails/mongoid.rb:16:in `each'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/mongoid-2.0.0.rc.7/lib/rails/mongoid.rb:16:in `block in load_models'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/paths.rb:102:in `block in each'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/paths.rb:102:in `each'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/paths.rb:102:in `each'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/mongoid-2.0.0.rc.7/lib/rails/mongoid.rb:15:in `load_models'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/mongoid-2.0.0.rc.7/lib/mongoid/railtie.rb:88:in `block (2 levels) in '
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/callbacks.rb:419:in `_run_prepare_callbacks'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/actionpack-3.0.3/lib/action_dispatch/middleware/callbacks.rb:40:in `initialize'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/actionpack-3.0.3/lib/action_dispatch/middleware/stack.rb:33:in `new'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/actionpack-3.0.3/lib/action_dispatch/middleware/stack.rb:33:in `build'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/actionpack-3.0.3/lib/action_dispatch/middleware/stack.rb:79:in `block in build'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/actionpack-3.0.3/lib/action_dispatch/middleware/stack.rb:79:in `each'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/actionpack-3.0.3/lib/action_dispatch/middleware/stack.rb:79:in `inject'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/actionpack-3.0.3/lib/action_dispatch/middleware/stack.rb:79:in `build'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/application.rb:162:in `app'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/application/finisher.rb:35:in `block in'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/initializable.rb:25:in `instance_exec'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/initializable.rb:25:in `run'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/initializable.rb:50:in `block in run_initializers'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/initializable.rb:49:in `each'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/initializable.rb:49:in `run_initializers'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/application.rb:134:in `initialize!'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/application.rb:77:in `method_missing'
    config/environment.rb:8:in `'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:239:in `block in require'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:225:in `block in load_dependency'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:596:in `new_constants_in'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:225:in `load_dependency'
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:239:in `require'
    spec/spec_helper.rb:9:in `block in '
    /Users/sean/.rvm/gems/ruby-1.9.2-p136/gems/spork-0.9.0.rc3/lib/spork.rb:23:in `prefork'
    规范/spec_helper.rb:4:in `'

更新:我的 spec_helper.rb

require 'rubygems'
require 'spork'

ENV["RAILS_ENV"] = "test"

Spork.prefork do
  require File.expand_path(File.dirname(__FILE__) + '/../config/environment')
  require 'rspec/rails'
end

Spork.each_run do
  # Hub::Application.reload_routes!
end

Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}

如果我移出require File.expand_path(File.dirname(__FILE__) + '/../config/environment')prefork,我的模型没有预加载,但正如您所料,运行我的测试需要更长的时间。

关于如何让 spork 不在 Rails 3 应用程序上加载模型的任何想法?我尝试过使用 spork 0.8.4,master 分支,目前是 0.9.0.rc3。有谁知道如何避免预加载模型?

4

4 回答 4

17

经过很长时间旋转我的轮子,我终于有了可以接受的东西:

Spork.prefork do
  require "rails/mongoid"
  Spork.trap_class_method(Rails::Mongoid, :load_models)

  # The following does not work correctly with Devise's routes that load the User model. 
  # Results in NameError unintitialized *
  # :reload_routes! triggers :devise_for which loads and caches the User class.
  # https://github.com/timcharper/spork/wiki/Spork.trap_method-Jujutsu
  # require "rails/application"
  # Spork.trap_method(Rails::Application, :reload_routes!) 

  require 'factory_girl_rails'
  Spork.trap_class_method(Factory, :find_definitions)

  require File.expand_path(File.dirname(__FILE__) + '/../config/environment')

end

问题主要是由于 Rails::Mongoid#load_models。在检查了 spork 的调试输出和加载事物的回溯之后,提供了一些关于加载模型的线索。此页面更详细地介绍了https://github.com/timcharper/spork/wiki/Spork.trap_method-Jujutsu,但我没有找到 :reload_routes!帮助设计强制用户类被预加载。

我的规格现在运行得更快。如果我能让我的用户模型不被缓存,我会很幸福,但在那之前,我会很满意。

于 2011-02-16T09:12:57.110 回答
8

我在 RSpec 和 Cucumber on Rails 3.1 中都有以下设置,并且模型令人耳目一新:

在 Gemfile 中设置require => falsefactory_girls_rails

gem 'factory_girl_rails', :require => false

用以下代码替换 Spork.prefork 和 Spork.each_run 块。

if Spork.using_spork?

  ActiveSupport::Dependencies.clear
  ActiveRecord::Base.instantiate_observers

  Spork.prefork do

  end

  Spork.each_run do
    require 'factory_girl_rails'

    # reload all the models
    Dir["#{Rails.root}/app/models/**/*.rb"].each do |model|
      load model
    end

    # reload routes
    Rails.application.reload_routes!

  end

end
于 2011-11-30T10:58:44.290 回答
7

此处建议的以下解决方案对我有用。它还重新加载用户模型。

# env.rb
Spork.each_run do
  require 'factory_girl_rails'
  # reload all the models
  Dir["#{Rails.root}/app/models/**/*.rb"].each do |model|
    load model
  end
end
于 2011-09-19T17:33:38.353 回答
3

这个解决方案对我有用(来自http://my.rails-royce.org/2011/03/17/rspec-2-and-fixtures/

Spork.prefork do
  require 'rails/application'
  Spork.trap_method(Rails::Application, :reload_routes!)
  Spork.trap_method(Rails::Application::RoutesReloader, :reload!) 
  Spork.trap_method(Rails::Application, :eager_load!)
  require File.expand_path("../../config/environment", __FILE__)
  Rails.application.railties.all { |r| r.eager_load! }

  require 'rspec/rails'

  RSpec.configure do |config|
     ...
  end
end

请注意,在 each_run 中执行“加载模型”只是部分解决方案,这将重新评估模型代码,但例如在删除模型方法后,它仍将存在于内存中,直到您重新启动 Spork。

于 2012-06-29T11:30:35.537 回答