将帮助程序文件加载到 FactoryBot 文件中会出现“无法加载此类文件”
Loading helper files into FactoryBot files gives `cannot load such file`
我试图在我的 FactoryBot
文件中使用辅助方法,但是当我调用 require rails_helper
时,我得到一个 require: cannot load such file -- support/geocoder_helper (LoadError)
.
spec/factories/members.rb
# frozen_string_literal: true
require 'rails_helper'
require 'support/geocoder_helper'
FactoryBot.define do
factory :member do
association :user, roles: ['Member']
cohort
after(:build) do |member, _evaluator|
if member.user
add_geocoder_stub(member.user.full_address_string)
end
end
end
end
spec/support/geocoder_helper.rb
# frozen_string_literal: true
DEFAULT_GEOCODER_STUB_RESULTS = [
{
'coordinates' => [11, -13],
'address' => '123 Main St, Los Angeles, CA, USA',
'state' => 'Los Angeles',
'state_code' => 'CA',
'country' => 'United States',
'country_code' => 'US'
}.freeze
].freeze
def add_geocoder_stub(address, results = DEFAULT_GEOCODER_STUB_RESULTS)
address = User.new(address).full_address_string if address.is_a?(Hash)
Geocoder::Lookup::Test.add_stub(address, results)
end
spec/support/factory_bot.rb
# frozen_string_literal: true
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end
spec/rails_helper.rb
# frozen_string_literal: true
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
...
结果:
in `require': cannot load such file -- support/geocoder_helper (LoadError)
这个结果对于所有不同的助手和所有工厂都是一样的。
我可以使用相同的 require
模式在非 FactoryBot 文件中使用助手。
版本:
rails (5.2.4.6)
rspec (3.9.0)
factory_bot (4.10.0)
spec
文件夹不在您的 load_path
中。您可以:
使用绝对路径require Rails.root.join('support/geocoder_helper')
使用相对要求require_relative '../support/geocoder_helper'
将 spec
文件夹添加到您的加载(在 spec_helper.rb 中):$LOAD_PATH << Rails.root.join('spec')
需要 spec_helper 中的所有支持文件,这是非常标准的程序
其他问题:不要在 main
对象 上定义方法。这是一个非常糟糕的做法,我一直在大多数规范中进行修复,导致许多非常奇怪的行为和细微的错误。加载 geocoder_helper 文件后,add_geocoder_stub
方法在 Object
class 上定义,使其在全局的每个对象中可用(包括 nil
、true
、所有符号等)。这只是,嗯,令人讨厌 - 更不用说它可能会导致意外的行为变化,因为突然 respond_to?
将 return 为真,你只是不知道其他库可能正在使用它。
相反,将您的方法包装在模块中:
module GeocoderHelper
module_function
DEFAULT_GEOCODER_STUB_RESULTS = [
...
].freeze
def add_geocoder_stub(address, results = DEFAULT_GEOCODER_STUB_RESULTS)
address = User.new(address).full_address_string if address.is_a?(Hash)
Geocoder::Lookup::Test.add_stub(address, results)
end
end
并仅在需要时使用它:
after(:build) do |member, _evaluator|
if member.user
GeocoderHelper.add_geocoder_stub(member.user.full_address_string)
end
end
RSpec.configure do |rspec|
rspec.include GecoderHelper
end
编辑
您似乎可以从规范文件中获取支持文件,这意味着您已经执行了上面的选项 3,但在此之前需要 FactoryBot(最有可能在捆绑程序设置中)。修复它的一种选择是从以下位置修改您的 Gemfile:
gem 'factory_bot_rails'
至
gem 'factory_bot_rails', require: false
这将阻止在 Bundler 设置中加载工厂。然后,您需要使用 require 'factory_bot_rails'
在 将规范添加到您的加载路径之后手动加载它们 - 很可能在您的 spec_helper 中(但也要检查您的 rails_helper, config/environments/test.rb 和初始值设定项).
我试图在我的 FactoryBot
文件中使用辅助方法,但是当我调用 require rails_helper
时,我得到一个 require: cannot load such file -- support/geocoder_helper (LoadError)
.
spec/factories/members.rb
# frozen_string_literal: true
require 'rails_helper'
require 'support/geocoder_helper'
FactoryBot.define do
factory :member do
association :user, roles: ['Member']
cohort
after(:build) do |member, _evaluator|
if member.user
add_geocoder_stub(member.user.full_address_string)
end
end
end
end
spec/support/geocoder_helper.rb
# frozen_string_literal: true
DEFAULT_GEOCODER_STUB_RESULTS = [
{
'coordinates' => [11, -13],
'address' => '123 Main St, Los Angeles, CA, USA',
'state' => 'Los Angeles',
'state_code' => 'CA',
'country' => 'United States',
'country_code' => 'US'
}.freeze
].freeze
def add_geocoder_stub(address, results = DEFAULT_GEOCODER_STUB_RESULTS)
address = User.new(address).full_address_string if address.is_a?(Hash)
Geocoder::Lookup::Test.add_stub(address, results)
end
spec/support/factory_bot.rb
# frozen_string_literal: true
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end
spec/rails_helper.rb
# frozen_string_literal: true
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
...
结果:
in `require': cannot load such file -- support/geocoder_helper (LoadError)
这个结果对于所有不同的助手和所有工厂都是一样的。
我可以使用相同的 require
模式在非 FactoryBot 文件中使用助手。
版本: rails (5.2.4.6)
rspec (3.9.0)
factory_bot (4.10.0)
spec
文件夹不在您的 load_path
中。您可以:
使用绝对路径
require Rails.root.join('support/geocoder_helper')
使用相对要求
require_relative '../support/geocoder_helper'
将
spec
文件夹添加到您的加载(在 spec_helper.rb 中):$LOAD_PATH << Rails.root.join('spec')
需要 spec_helper 中的所有支持文件,这是非常标准的程序
其他问题:不要在 main
对象 上定义方法。这是一个非常糟糕的做法,我一直在大多数规范中进行修复,导致许多非常奇怪的行为和细微的错误。加载 geocoder_helper 文件后,add_geocoder_stub
方法在 Object
class 上定义,使其在全局的每个对象中可用(包括 nil
、true
、所有符号等)。这只是,嗯,令人讨厌 - 更不用说它可能会导致意外的行为变化,因为突然 respond_to?
将 return 为真,你只是不知道其他库可能正在使用它。
相反,将您的方法包装在模块中:
module GeocoderHelper
module_function
DEFAULT_GEOCODER_STUB_RESULTS = [
...
].freeze
def add_geocoder_stub(address, results = DEFAULT_GEOCODER_STUB_RESULTS)
address = User.new(address).full_address_string if address.is_a?(Hash)
Geocoder::Lookup::Test.add_stub(address, results)
end
end
并仅在需要时使用它:
after(:build) do |member, _evaluator|
if member.user
GeocoderHelper.add_geocoder_stub(member.user.full_address_string)
end
end
RSpec.configure do |rspec|
rspec.include GecoderHelper
end
编辑
您似乎可以从规范文件中获取支持文件,这意味着您已经执行了上面的选项 3,但在此之前需要 FactoryBot(最有可能在捆绑程序设置中)。修复它的一种选择是从以下位置修改您的 Gemfile:
gem 'factory_bot_rails'
至
gem 'factory_bot_rails', require: false
这将阻止在 Bundler 设置中加载工厂。然后,您需要使用 require 'factory_bot_rails'
在 将规范添加到您的加载路径之后手动加载它们 - 很可能在您的 spec_helper 中(但也要检查您的 rails_helper, config/environments/test.rb 和初始值设定项).