Reputation: 196
In my Ruby on Rails project I have some files in spec/support
that are dependent on other files within the same directory.
#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
In order for Foo.new.hello_world
to work in a spec, I must explicitly prefix the dependent file with require_relative("bar/bar")
.
#spec/support/page_objects/foo.rb
require_relative("bar/bar")
class Foo
include Bar
end
I would prefer not to have to explicitly call require
in all of my dependent files.
All of my spec/support
files are loaded per this line of the spec/rails_helper.rb
.
#spec/rails_helper.rb
Dir[Rails.root.join("spec", "support", "**", "*.rb")].sort.each { |f| require f }
I have determined that changing this line and explicitly loading dependencies first, will work.. But I am looking for a cleaner more long term solution.
I do not want to have to explicitly call require
in all of my dependent files, nor do I want to have to name all of my dependencies in the above block for the sake of load order.
I just want it to work typical to how app/models
works when using dependencies in development.
Is there a way to accomplish this?
Upvotes: 1
Views: 1019
Reputation: 102218
You can use the auto-loader to load constants:
# config/environments/test.rb
config.autoload_paths << Rails.root.join('spec/support')
Its behavior differs slightly if we are talking about Zeitwerk or the classic autoloader. But adding a path to the autoloader paths means that the auto loader will look for Foo
in spec/support/foo.rb
as well as app/**/foo.rb
.
But the real question is why your using classes/modules so extensively instead of RSpec's higher level constructs such as shared contexts or factories.
Upvotes: 2