如何在不明确要求依赖项的情况下加载 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 或工厂。
在我的 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 或工厂。