如何在不明确要求依赖项的情况下加载 Rspec 中的订单依赖支持文件?

How do I load order dependent support files in Rspec without explicitly requiring the dependencies?

在我的 Ruby Rails 项目中,我在 spec/support 中有一些文件依赖于同一目录中的其他文件。

#spec/support/page_objects/foo.rb

class Foo
  include Bar
end

#spec/support/page_objects/bar/bar.rb

module Bar
  def hello_world
    "Hello World"
  end
end

为了 Foo.new.hello_world 在规范中工作,我必须明确地在依赖文件前加上 require_relative("bar/bar")

#spec/support/page_objects/foo.rb

require_relative("bar/bar")

class Foo
  include Bar
end

我宁愿不必在所有依赖文件中显式调用 require

我的所有 spec/support 文件都是根据 spec/rails_helper.rb 的这一行加载的。

#spec/rails_helper.rb

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

我确定更改此行并首先显式加载依赖项会起作用。但我正在寻找更清洁、更长期的解决方案。

我不想在我的所有依赖文件中显式调用 require,我也不想为了加载顺序而必须在上面的块中命名我的所有依赖项。

我只是希望它能像 app/models 在开发中使用依赖项时的典型工作方式一样工作。

有办法做到这一点吗?

您可以使用自动加载器加载常量:

# config/environments/test.rb
config.autoload_paths << Rails.root.join('spec/support')

如果我们谈论的是 Zeitwerk 或经典的自动加载器,它的行为会略有不同。但是向自动加载器路径添加路径意味着自动加载器将在 spec/support/foo.rb 以及 app/**/foo.rb.

中查找 Foo

但真正的问题是为什么您如此广泛地使用 classes/modules 而不是 RSpec 的更高级别的构造,例如 shared contexts 或工厂。