rspec,factory_girl和datamapper的spork和cache_classes问题

spa*_*ovv 13 rspec ruby-on-rails datamapper spork factory-bot

我有Spork测试服务器的问题.

如果我在config/environments/test.rb中设置config.cache_classes = false,那么规范就会开始出现rasie错误.

Failure/Error: task = Factory(:something, :foo => @foo, :bar => @bar)
     DataMapper::ImmutableError:
       Immutable resource cannot be modified
Run Code Online (Sandbox Code Playgroud)

这是我的spec_helper.rb:

require 'spork'

Spork.prefork do
  if ENV['CODE_COVERAGE'] == '1'
    require 'simplecov'
    SimpleCov.start 'rails'
  end

  ENV["RAILS_ENV"] ||= 'test'
  require File.expand_path("../../config/environment", __FILE__)
  require 'rspec/rails'
  require 'webmock/rspec'
  require 'factory_girl'

  Dir[Rails.root.join("spec/controllers/shared/*.rb")].each { |f| require f }
  Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

  RSpec.configure do |config|
    config.mock_with :mocha
    config.include Rails.application.routes.url_helpers
    config.include UrlHelper

    config.before(:each) do
      repository(:default) do
        transaction = DataMapper::Transaction.new(repository)
        transaction.begin
        repository.adapter.push_transaction(transaction)
      end
    end

    config.after(:each) do
      repository(:default).adapter.pop_transaction.try(:rollback)
    end

  end
end

# This code will be run each time you run your specs.
Spork.each_run do
  # reload factories
  Factory.definition_file_paths = Dir[File.join(Rails.root, "spec", "factories")]
  Factory.find_definitions

  DatabaseCleaner.strategy = :truncation
  DatabaseCleaner.clean
  LoggedEvent.all.destroy!

end
Run Code Online (Sandbox Code Playgroud)

当我有config.cache_classes = true时,一切都运行良好,但它没有重新加载模型,控制器类,所以在这种情况下我没有看到使用spork的重点.

当cache为true时,我尝试添加到spec_helper.rb这样的东西:

Spork.each_run do
    Dir.glob("#{Rails.root}/app/models/*.rb").sort.each { |file| load file }
end
Run Code Online (Sandbox Code Playgroud)

但我不喜欢这个解决方案.

sol*_*nic 20

只需添加:

ActiveSupport::Dependencies.clear
Run Code Online (Sandbox Code Playgroud)

到prefork块结束.这将负责清理模型.

此外,您希望将rspec配置包含移动到Spork.each_run,同样需要规范支持和共享文件.

这是有效的,我在2个项目中使用此设置,没有任何麻烦.

  • 等等,`ActiveSupport :: Dependencies.clear`也属于prefork或each_run吗?我见过相互矛盾的故事.两者似乎都不适合我,两者都导致加载问题:"预期xxxx定义xxxx." 另外,单独使用"ActiveSupport :: Dependencies.clear"解决了这个问题吗?或者是否需要与原始问题中的each_run示例一起使用? (3认同)
  • 这种方法是一种解决方法.我的猜测是,真正的问题是你在Spork.prefork中运行的代码正在加载模型.我遇到了类似的问题,我可以通过调用`spork --diagnose`来调试它.它将列出Spork加载的所有文件以及加载每个文件的回溯.在我的情况下,我有一个引用控制器的初始化程序,导致该控制器的问题不在每次测试运行时重新加载. (2认同)

Nat*_*ong 8

试试ActionDispatch :: Reloader

除了设置config.cache_classes = falseconfig/environments/test.rb,下面似乎让DataMapper的和叉勺发挥很好了我们的团队:

Spork.each_run do

  # Routes
  MyApp::Application.reload_routes!

  if Spork.using_spork?
    # Reload all app files
    ActionDispatch::Reloader.cleanup!
    ActionDispatch::Reloader.prepare!

    # All factories
    FactoryGirl.reload
  end

end
Run Code Online (Sandbox Code Playgroud)