RSpec 在没有实际文件的模块中测试 class

RSpec test class from within a module without the actual file

我有一个用于在我的商店中创建零件(产品)的模块,名为 ErpPartsService::Builder,并且使用该模块我构建了一个助手 class CategoryByLauberIdFetcher,我只是在内部使用模块,而不是其他任何地方。我在文件 app/services/erp_parts_service/builder.rb 中有它。

这是我的代码:

module ErpPartsService
  class CategoryByLauberIdFetcher < Service # This is the helper class that I want to test.
    def initialize(...)
      ...
    end

    def call(lauber_id:)
      ...
    end
  end

  class Builder < Service
    def initialize(
      category_by_lauber_id: CategoryByLauberIdFetcher
    )
      @category_by_lauber_id = category_by_lauber_id
    end

    def call(...)
      ...
    end

    private

    def get_category_by_lauber_id(id)
      @category_by_lauber_id.call(lauber_id: id)
    end
  end
end

我在 spec/services/erp_parts_service/category_by_lauber_id_fetcher_spec.rb

中为 CategoryByLauberIdFetcher 编写了测试
RSpec.describe ErpPartsService::CategoryByLauberIdFetcher do
  it '...' do
    ...
  end
end

当我 运行 他们时,我得到:

NameError:
  uninitialized constant ErpPartsService::CategoryByLauberIdFetcher

我在 Builder class 中编写了测试 spec/services/erp_parts_service/builder_spec.rb

RSpec.describe ErpPartsService::Builder do
  it '...' do
    ...
  end
end

而且它们工作正常。我错过了什么?

看起来像是自动加载器问题:

  1. 看到常量 ErpPartsService::Builder 自动加载器需要一个文件 erp_parts_service/builder.rb 并且它找到了...但是

  2. 看到 ErpPartsService::CategoryByLauberIdFetcher 自动加载器试图找到 erp_parts_service/category_by_lauber_id_fetcher.rb 但失败了,因为这个 class 的定义在 erp_parts_service/builder.rb

添加 require 以显式加载包含您要测试的 class 的文件。

require 'erp_parts_service/builder.rb'
RSpec.describe ErpPartsService::CategoryByLauberIdFetcher do
  it '...' do
    ...
  end
end

或者(更好)将每个 class 放在一个单独的文件中并遵守约定。不仅是自动加载器,加入您项目的其他人也会在不存在的文件中查找此 class。

我知道你提到过你只想在你的模块中使用这个 class,但这不是实现它的方法 "private"。你只是让使用它变得很烦人,而不是保护它不被使用。