如何在 spec/support/` 中为 Ruby 在 Rails RSpec 测试中使用模块

How do I use modules in `spec/support/` for Ruby on Rails RSpec tests

我想在 Rails 项目的典型 Ruby 中正确使用 spec/support/ rspec 目录中的 module 文件。

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

module Foo
  module Bar  
    def hello
      "hello world"
    end
  end
end

# spec/support/page_objects/foo/foo_bar.rb

class FooBar
  include Foo::Bar
end

# spec/system/foo_bars/create_spec.rb

RSpec.describe "Create FooBar", type: :system do
  it "returns hello world"
    expect(FooBar.new.hello).to eq "hello world"
  end
end

我希望 rspec spec/foo_bars/create_spec.rb 通过,但我收到 uninitialized constant Foo::Bar

我让它工作的唯一方法是在 class 文件中要求模块。

# spec/support/page_objects/foo/foo_bar.rb

require_relative("bar")

class FooBar
  include Foo::Bar
end

有没有办法正确使用 spec/support 中的 module 文件来避免显式调用 require

默认情况下 spec 中的任何内容都不会自动加载。

通常在 spec/rails_helper.rb

中添加一行以加载 spec/support 个文件
Dir[Rails.root.join('spec/support/**/*.rb')].sort.each { |f| require f }

请注意,这将增加所有测试运行的加载时间,无论它们是否使用您的支持文件。这对于一般用途的支持文件来说很好,但对于特定于单个 class 的支持文件来说不是一个好主意。那些测试 classes 会污染每个测试。

相反,请考虑将它们写成 shared context 并根据需要包含在内。将它们放在 shared_context 目录中。您还可以加载所有共享上下文和示例。

Dir[Rails.root.join('spec/**/shared*/*.rb')].sort.each { |f| require f }

请注意 spec/support/page_objects/foo/foo_bar.rb 通常用于 Foo::FooBar。 FooBar 应该进入 spec/support/page_objects/foo_bar.rb。这对您的代码没有 material 影响,但命名符合 Rails 标准是件好事。