将帮助文件加载到 FactoryBot 文件中会导致“无法加载此类文件”[重复]

Posted

技术标签:

【中文标题】将帮助文件加载到 FactoryBot 文件中会导致“无法加载此类文件”[重复]【英文标题】:Loading helper files into FactoryBot files gives `cannot load such file` [duplicate] 【发布时间】:2021-12-21 14:05:13 【问题描述】:

我试图在我的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 文件中使用帮助程序。

版本: 导轨 (5.2.4.6)

rspec (3.9.0)

factory_bot (4.10.0)

【问题讨论】:

【参考方案1】:

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 文件后,在 Object 类上定义 add_geocoder_stub 方法,使其在全局每个对象中都可用(即包括 niltrue、所有符号等)。这只是,好吧,令人讨厌 - 更不用说它可能会导致意外的行为变化,因为突然 respond_to? 将返回 true 而你只是不知道其他库可能正在使用它。

相反,将您的方法包装在模块中:

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 和初始化程序)。

【讨论】:

如果 'spec' 不在我的加载路径中是一个问题,为什么我可以在 'spec' 目录内的其他文件中使用 require 'support/geocoder_helper' 并且它可以工作?它只与 FactoryBot 中断 @TheCaptan - 回答已编辑

以上是关于将帮助文件加载到 FactoryBot 文件中会导致“无法加载此类文件”[重复]的主要内容,如果未能解决你的问题,请参考以下文章

从FactoryGirl更新到factoryBot会导致NoMethodError

在 factorybot 中附加 ActiveStorage 文件

FactoryGirl / Bot图像定义

如何将 JSON 文件加载到 Redshift 表的单个列

将文件添加到 zip 中会添加包含文件的文件夹

ROS Gazebo 加载模型失败问题